调用 wait() 不会停止正确的线程



我是Java中多线程的新手。我正在尝试运行一个可以模拟多个将数据写入输出的程序。

我希望作家在某个时候都停下来,所以我在他们身上打电话给wait(),但这不起作用。我知道问题发生在哪里,但我不知道为什么会发生。

public void run() {
    ExecutorService executor = Executors.newFixedThreadPool(nbOfWriters);
    try {
        // Create a list with all the writers that should run at the same time
        Writer[] writers = new Writer[nbOfWriters];
        for (int i = 0; i < nbOfWriters; i++) {
            writers[i] = new Writer(i);
            executor.execute(writers[i]);
        }
        /*
        Expected outcome:
        start every writer -> wait 3 seconds
        pause every writer -> wait 3 seconds
        run every writer -> wait 3 seconds
        end
        */
        TimeUnit.SECONDS.sleep(3);
        for (Writer writer : writers) {
            synchronized (writer) {
                System.out.println("HERE 1");
                writer.wait();
                System.out.println("HERE 2");
            }
        }
        TimeUnit.SECONDS.sleep(3);
        for (Writer writer : writers) {
            synchronized (writer) {
                writer.notify();
            }
        }
        Thread.sleep(3);
        // End of the test
        for (Writer writer : writers) writer.end();
    } 
    catch (InterruptedException ex) {
        System.out.println(ex.getMessage());
    }
    finally {
        try {
            executor.shutdown();
            executor.awaitTermination(5, TimeUnit.SECONDS);
        } 
        catch (InterruptedException ex) {
            ex.getMessage();
        }
        finally {
            executor.shutdownNow();
        }
    }
}

作家只是将东西写为输出(在这里不重要)。我添加了打印语句"此处1"one_answers"在这里2",以显示程序失败的位置。基本上从未达到"这里2"。

从理论上讲,应该发生的是我将数据写入输出3秒,然后在3秒内没有任何内容,然后再次写入数据作为输出。

实际输出是:东西被写入输出3秒。"这里1"打印。东西继续显示为输出,没有停顿,没有"这里2",并且程序永远不会停止。

在我看来,wait()停止了错误的线程。

writer.wait()不应该像其他方法一样在特定的作者线程中呼叫等待?

no。

语句writer.wait();使用writer对象作为A Monitor 。监视器的使用方式非常特定*。它允许一个线程等待一些(可能未知)的其他线程来完成任务。想要进行等待的线程通过调用o.wait();

来做到这一点

无法使一个线程使 make 另一个线程调用函数。一个线程无法完成另一个线程完全做任何事情。线程执行他们正在执行的代码告诉他们要做的代码,并且在设计良好的程序中,该代码告诉他们彼此合作合作。线程a到 ask thread B有多种方法可以做某事,但要 you 编写在线程A中运行的代码以进行询问,并且已经上了给您编写在遇到何时被问到的线程B中运行的代码,然后做任何事情。


*请参阅oracle"守卫块"教程。
笔记!该教程不使用"监视器"一词,但它谈论了相同的模式。

wait()的文档说:

使当前线程等到另一个线程调用notify()方法或此对象的notifyall()方法。

所以主线程是在"HERE 2"之前等待的,并且由于它被卡住了,因此永远无法到达notify

我不确定是否有明确的方法来完成您想要的工作(告诉另一个线程等待)。

最新更新