java - 在消费者线程收到同步更改通知并退出后,处理生产者线程的正确方法是什么?

标签 java concurrency producer-consumer

我的理解是,在消费者收到同步变量更改的通知后,如果消费者Thread退出并退出,则没有什么可以阻止生产者继续运行。处理生产者线程的正确方法是什么?是否有任何东西阻止从消费者的 run() 方法调用 Thread.interrupt()

我正在尝试执行以下操作:

//in consumer
public void run() {
    synchronized( checkSolution) {
        while (!checkSolution.getIsSolutionValid) {
            try{
                checkSolution.wait()
            } catch( InterruptedException ignore) {}
        } 
        //valid soln received
        System.out.println("reference");
        checkSolution.interrupt();
        doAmazingWorkWithSolution();
    }
    //MARK
}
//in producer (checkSolution)
public synchronized boolean getIsSolutionValid() { return isSolutionValid; }
public void run() {
    while(true) {
        try{
            synchronized( this) {
                if( fSolution.size() != correctSize) {
                    isSolutionValid = false;
                    Thread.sleep(500);
                 } else {
                     System.out.println(" Solution is correct size.");
                     isSolutionValid = true;
                     notifyAll();
                 }  
             }
         } catch(InterruptedException ie) {
             //Thread.currentThread().interrupt();
             return;
    }
    }
}

现在,这是我注意到但我真的不明白的:

  1. 在任何成功的中断下,生产者的中断标志都会被设置,但它会在最终关闭之前多次执行 else block 中的代码。如何避免在 notify 期间发送垃圾邮件 if/else 语句?

  2. 如果我将 checkSolution.interrupt() 和“amazing work”方法调用移动到标记为 //MARK 的行,它的中断速度会明显变慢,执行惊人的工作调用,但奇怪的是从不打印 `println("reference");

  3. 如果我从 InterruptedException 中删除 return 语句,它会收到中断并最终在 Exception block 中执行一步,但会向 else 语句发送无数次垃圾邮件,然后开始再次插入 Thread.sleep block ,就好像中断标志已被重置一样。

  4. 生产者的 InterruptException 中的 Thread.currentThread().interrupt(); 是我在其他人的代码中看到的东西,但无论我是否包含它,它在这里似乎都没有执行任何操作。

这些都是我感到困惑的小事情。主要问题是在消费者获得所需内容后,如何尽可能高效地关闭生产者,并尽可能靠近消费者线程。

最佳答案

我认为你的工作水平太低了。如果只有一个生产者和消费者,您可以使用 java.util.concurrent.SynchronousQueue 来阻塞消费者,直到生产者完成其工作。

有关Thread.currentThread().interrupt()的用途,请参见http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html 。这样做是个坏主意

catch( InterruptedException ignore) {}

while 循环中。更多详细信息请参阅链接的文章。

关于java - 在消费者线程收到同步更改通知并退出后,处理生产者线程的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9733704/

相关文章:

如果包含 time.Sleep,Goroutine 不会执行

java - 并行流概念

java - 无法使用java从rabbitmq中的传递回调 block 分配消息

c - 使用信号量的有界缓冲区生产者-消费者代码

java - 使用 intelliJ IDEA 开发 OSGi

java - JFreeChart图表渲染问题

java - 从图像样本中获取卷积矩阵?

java - 如何让 Ant sshexec 使用非空密码

c# - 使用 Parallel.foreach 时未获得正确的 http 查询并行度

c - pthreads的生产者消费者问题