我可以使用PipedStreams将数据从一个线程发送到多个其他线程吗?

时间:2014-12-26 01:59:58

标签: java multithreading inputstream outputstream

我正在编写一个多线程服务器,我为每个客户端套接字连接都有一个线程。 我想将来自主线程的数据来回传递给客户端线程。

我需要设置多少个线程?

它是否像这样工作:

[服务器类:]

private PipedInputStream serverInputStream = new PipedInputStream();
private PipedOutputStream serverOutputStream = new PipedOutputStream();
public PipedInputStream clientInputStream = new PipedInputStream();
public PipedOutputStream clientOutputStream = new PipedOutputStream();

serverInputStream.connect(clientOutputStream);
clientInputStream.connect(serverOutputStream);

或者我是否必须为每个客户设置这四个Streams?

如果这个问题可能很愚蠢,我道歉,但我已经看到这是一个拥有并尝试过它。 如果有更好的方法来处理线程之间的通信,那么请教育我!

我编写了一个小类,它等待阻塞并将消息添加到队列的缓冲读取器:

public class DataListener implements Runnable {

    private InputStream is;
    private ConcurrentLinkedQueue<String> messages;
    private boolean closed = false;

    public DataListener(InputStream is, ConcurrentLinkedQueue<String> messages) {
        this.is = is;
        this.messages = messages;
    }

    @Override
    public void run() {
        BufferedReader br = new BufferedReader(new InputStreamReader(is));

        while (!closed) {
            try {
                messages.add(br.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void close() {
        closed = true;
    }
}

你能否告诉我这是否是一种解决阻塞听众问题的好方法?

2 个答案:

答案 0 :(得分:0)

使用流将数据从一个线程传递到另一个线程绝对不是一个好主意,因为:

  • 流IO是阻塞操作,这会使线程保持不变。
  • Streams(一般情况下)默认情况下不是线程安全的,这可能会导致各种问题。

如果要在线程之间传递数据,请尽量避免阻塞,否则服务器线程将在大多数时间等待。 Java提供了一个广泛的非阻塞数据交换功能工具集,您可以使用它,您可以在Concurrent Package中找到它。

一种非常简单但有效且快速的数据交换方式是使用消息式系统:

final ConcurrentLinkedQueue<MyMessageClass> messages = new ConcurrentLinkedQueue<MyMessageClass>();

public void addMessage(final MyMessageClass message) {
  messaged.add(message);
}

protected void serverLoop() {
  //...
  final MyMessageClass message = messages.poll(); // does not block, returns null if none is available
  if (message != null) {
    handleMessage(message);
  }
  //...
}

您可以使用LinkedBlockingQueue等其他类来获取临时阻止等其他功能。

然而:当涉及到线程化时,大多数问题只能通过使用正确的架构来解决您手头的问题。没有&#34;金锤&#34;所有线程任务的解决方案,如果您希望代码运行完美,您需要找到合适的解决方案。

答案 1 :(得分:0)

您只能在两个线程之间使用任何给定的管道蒸汽对。每个线程对需要一对pioed流。不要这样做。使用队列。