首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >循环屏障再利用?

循环屏障再利用?
EN

Stack Overflow用户
提问于 2013-10-12 00:38:26
回答 1查看 948关注 0票数 1

我目前正在尝试实现一个应用程序来与一台机器通信,它基本上应该按照以下方式工作:

  • 程序向服务器发送一条消息(在本例中,文件的前255个字节)。
  • 机器以“成功接收到的消息”或“错误接收消息”响应。
  • 然后,程序必须根据机器的响应来决定是否发送下一条消息(下255字节)(最后一条消息上的错误,必须重新启动)。
  • 等等,对于程序需要发送的每一条消息(取决于文件的大小)。

因此,我们认为有一个线程来执行发送,另一个线程执行接收,因为我们有一个api将一个类注册为从机器接收消息的类(仅通过实现一个接口),并且向机器发送消息的方法不是阻塞类型的,所以需要一种等待机器响应的方法,以便程序能够在响应到达后决定要做什么。

因此,我们需要以某种方式同步这两个线程,因为可以确定它们将交换多少消息,这使我们尝试了一个CyclicBarrier。这是用于测试CyclicBarrier是否会帮助我们解决这个问题的代码(程序实际上并不使用套接字与机器通信,这只是用于测试屏障):

代码语言:javascript
复制
import java.io.*;
import java.net.*;
import java.util.concurrent.*;

public class BlockingTest{
  private CyclicBarrier barrier;

  class Receiver implements Runnable{
    @Override public void run(){
      try{
        ServerSocket ss = new ServerSocket(8080);
        while(!barrier.isBroken()){
          System.out.println("Waiting message...");
          Socket response = ss.accept();
          BufferedReader br = new BufferedReader(new InputStreamReader(
              response.getInputStream()));
          System.out.printf("Received: %s\n", br.readLine());
          barrier.await();
        }
      }catch(InterruptedException | BrokenBarrierException |
        IOException ex){
        System.err.println(ex.getMessage());
      }
    }
  }

  public BlockingTest(){
    this.barrier = new CyclicBarrier(2, new Runnable(){
      @Override public void run(){
        System.out.println("done.");
      }
    });

    new Thread(new Receiver()).start();

    try{
      Socket sender = new Socket("localhost", 8080);
      PrintWriter pw = new PrintWriter(sender.getOutputStream(), true);
      for(int i = 0; i < 3; i++){
        System.out.println("Sending message:");
        pw.println("Message!");
        this.barrier.await();
      }
    }catch(InterruptedException | BrokenBarrierException | IOException ex){
      System.err.println(ex.getMessage());
    }
  }

  public static void main(String[] arg){
    new BlockingTest();
  }
}

如果我们只发送一条消息(在BlockingTest()构造函数中为否块,只需发送消息),则此代码可以正常工作,但是在添加for块之后,它就不能像预期的那样工作了。它只在第一次工作,然后挂起:

代码语言:javascript
复制
Waiting message...
Sending message:
Received: Message!
done.
Waiting message...
Sending message:

问题如下:

  • 如何使屏障可重复使用?这是自动的还是必须用手做的?
  • 程序挂起是因为我漏掉了套接字(或屏障代码)吗?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-12 01:06:57

它挂起的原因是,您要打开一个连接到服务器,并继续向它发送数据,但是在接收端,您放弃了第一个连接,并开始等待下一个连接的发生。

您可以在每次发送数据时从发件人创建一个新连接。代码块

代码语言:javascript
复制
Socket sender = new Socket("localhost", 8080);
PrintWriter pw = new PrintWriter(sender.getOutputStream(), true);

必须在for循环中移动。(当然,要注意释放所有资源)

或,

将接收器从第一连接中读取数据,而不是等待第二包数据的新连接。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19329204

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档