两个线程如何在两个线程运行时进行通信?

ast*_*eri 6 java concurrency multithreading

我一直在努力教自己并发,我遇到了一个问题.我知道两个Java线程可以通过wait()和相互通信notify().但是,这需要一个线程处于非活动状态,并且基本上"只是坐在一起",直到另一个线程将其唤醒.

是否可以让两个线程同时运行并让它们监听另一个线程的通知?这是通过并发技术还是通过类似的方式实现的ActionListener

例如,我正在测试它的项目基本上是一个网格,其中不同的实体在不同的单元格中四处游荡.当两个实体碰巧徘徊在同一个单元格中时,我希望一个人通知另一个实体,并根据此情况发生不同的事情(例如,问候:"你好!").但就目前而言,使用wait/notify范例,其中一个线程/实体必须简单地坐在一个单元格中等待另一个进入; 他们不能同时四处走动.

Cli*_*iff 5

您可以通过几种方式在线程之间进行通信。使用最常见的方法,您可以使用实例变量在线程之间共享信息,但是您必须注意仅从一个线程写入信息或将任何更新同步到共享变量。另外,您可以使用专为线程间通信或在线程之间传递原始数据而设计的管道I / O流。一个线程将信息写入流,而另一个线程读取信息。

这是一个示例方法,该方法将从速度较慢的网络连接中读取输出,然后使用线程将其转储到System.out。

    public void threads() throws IOException {
    final PipedOutputStream outputForMainThread = new PipedOutputStream();
    new Thread(new Runnable() {
        @Override
        public void run() {
            while(moreDataOnNetwork()) {
                byte[] data = readDataFromNetwork();
                try {
                    outputForMainThread.write(data);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }).start();
    BufferedReader reader = new BufferedReader(new InputStreamReader(new PipedInputStream(outputForMainThread)));
    for(String eachLine = reader.readLine(); eachLine != null; eachLine = reader.readLine()) {
        System.out.println(eachLine);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,这听起来几乎像是您想要一种事件回调机制,其中在另一个线程检测到特定条件时通知一个线程(您的用户界面线程)。取决于您的平台,其中的很多内容都可以使用。例如,使用Android,您可以拥有一个确定网格实体已移动的线程。它将向主用户界面线程发送更新以重画屏幕。这样的更新可能类似于:

public void gridEntityDidUpdate(final Point fromLocation, final Point toLocation) {
    Activity activity = getMainActivity();
    activity.runOnUiThread(
            new Runnable() {
                @Override
                public void run() {
                    updateScreen(fromLocation, toLocation);
                    if(pointsAreCoincedent(fromLocation, toLocation)) {
                        System.out.println("Hello there!");
                    }
                }
            }
    );
}

private void updateScreen(Point fromLocation, Point toLocation) {
    //Update the main activity screen here
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您有一个后台线程可以计算所有屏幕上元素的位置,并在元素位置更改时通知主线程。有一种提取的方法可以确定2个点是巧合还是相同。