Java“会话” 2 个线程之间:管道输入/输出流

发布于 2024-10-23 19:58:26 字数 1436 浏览 7 评论 0原文

我想知道您认为实现两个线程交换字符串并相互响应的程序的最佳方法是什么。

我无法让它工作,无论是使用 java.nio.Pipe 还是 java.io.PipedInputStream / java.io.PipedOutput.Stream

这是我想要做的代码示例:

主类,设置一切。

public static void main(String[] args) {
        // TODO
        // Create two communication channel, and bind them together

        MyThread t1 = new MyThread(channel1Reader, channel2Writer, 0);
        MyThread t2 = new MyThread(channel2Reader, channel1Writer, 1);

        t1.run();
        t2.run();

    }

线程类:

public class MyThread extends Thread {
    private ? inputStream;
    private ? outputStream;
    private boolean canTalk;
    private int id;

    public MyThread(? inputStream, ? outputStream, boolean isStarting, int id) {
        this.inputStream = inputStream;
        this.outputStream = outputStream;
        this.canTalk = isStarting;
        this.id = id;
    }

    public void run() {
        while(true) {
            if(canTalk) {
                String s = getRandomWord();
                // TODO
                // Write s to the output stream
            }

            // TODO
            // Wait until receiving a String on the input stream
            String s2 = the word I just received
            Log.info("Thread " + id + " received the word '" + s2 + "'");
            canTalk = true;
            Thread.sleep(1000);
        }
    }

有什么想法吗?

谢谢!

I would like to know what is in your opinion the best way of implementing a program where two threads are exchanging Strings and responding to each other.

I couldn't get it to work, either with java.nio.Pipe and java.io.PipedInputStream / java.io.PipedOutput.Stream

Here is a code example of what I want to do:

The main class, setting everything up.

public static void main(String[] args) {
        // TODO
        // Create two communication channel, and bind them together

        MyThread t1 = new MyThread(channel1Reader, channel2Writer, 0);
        MyThread t2 = new MyThread(channel2Reader, channel1Writer, 1);

        t1.run();
        t2.run();

    }

The thread class:

public class MyThread extends Thread {
    private ? inputStream;
    private ? outputStream;
    private boolean canTalk;
    private int id;

    public MyThread(? inputStream, ? outputStream, boolean isStarting, int id) {
        this.inputStream = inputStream;
        this.outputStream = outputStream;
        this.canTalk = isStarting;
        this.id = id;
    }

    public void run() {
        while(true) {
            if(canTalk) {
                String s = getRandomWord();
                // TODO
                // Write s to the output stream
            }

            // TODO
            // Wait until receiving a String on the input stream
            String s2 = the word I just received
            Log.info("Thread " + id + " received the word '" + s2 + "'");
            canTalk = true;
            Thread.sleep(1000);
        }
    }

Any ideas?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

倾听心声的旋律 2024-10-30 19:58:26

如果您有一个必须采用输入/输出流的库,则 PipedInout/OutputStream 非常有用。否则是在线程之间交换数据的最不友好的方式之一。

然而,在线程之间交换数据的最简单方法是使用 ExecutorService。您可以提交 Callable;向服务发送任务并从 Future获取结果

另一种方法是使用多个 BlockingQueue但这并不能节省太多,并且缺乏 ExecutorService 为您提供的功能。

您的示例存在的问题是,作为单个线程实现要简单得多。我建议您查看最适合由多线程执行的功能。

PipedInout/OutputStream are useful if you have a library which has to take an input/output stream. Otherwise is one of the least friendly ways to exchange data between threads.

However, the simplest way to exchange data between threads is to use an ExecutorService. You can submit Callable<String> tasks to the service and get results from Future<String>

Another approach is to use multiple BlockingQueue<String> but this doesn't save much and lacks the functionality an ExecutorService gives you.

The problem you have with your example is it is much simpler to implement as a single thread. I suggest you look at functionality which is best performed by multiple threads.

甜妞爱困 2024-10-30 19:58:26

您在这里使用的是

    t1.run();
    t2.run();

当前线程中两个 Thread 对象的 run 方法,并且一个接一个地执行。构造的线程实际上并没有启动。

这样通信就无法进行,因为当写入线程写入时读取线程尚未启动,反之亦然。 此处使用用户

    t1.start();
    t2.start();

,或者使用带有 Runnable 对象的 ThreadPool,而不是 Thread 子类。

You are using here

    t1.run();
    t2.run();

This executes the run methods of both Thread objects in the current thread, and one after the other. The threads constructed are not actually started.

This way the communication can't work, since the reading thread is not yet started when the writing thread writes, and the other way around. User

    t1.start();
    t2.start();

here, or use a ThreadPool with Runnable objects, instead of Thread subclasses.

浮云落日 2024-10-30 19:58:26

我通常使用 Queue,可能由 LinkedList 支持。

读:

synchronized (q) {
    while (q.isEmpty() && !stopSignal) {
        q.wait(3000);
    }
    return q.poll();
}

写:

synchronized (q) {
    q.add(item);
    q.notify();
}

I usually use a Queue, likely backed by a LinkedList.

To read:

synchronized (q) {
    while (q.isEmpty() && !stopSignal) {
        q.wait(3000);
    }
    return q.poll();
}

To write:

synchronized (q) {
    q.add(item);
    q.notify();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文