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

时间:2012-03-16 07:54:10

标签: java concurrency producer-consumer

我的理解是,在消费者收到同步变量变更通知后,如果消费者Thread退出并退出,则没有什么能阻止生产者开始。处理生产者线程的正确方法是什么?是否有任何因阻止Thread.interrupt()方法调用run()的行为?

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

//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块中的代码。如何避免在notify

  2. 期间发出if / else语句的垃圾邮件
  3. 如果我将checkSolution.interrupt()和“神奇工作”方法调用移动到标记为//MARK的行,它会显着减慢中断,执行令人惊奇的工作调用,但奇怪的是从不打印`println(“参考“);

  4. 如果我从InterruptedException表单中删除了返回语句,它会收到中断并在Exception块中结束一步,但是将else语句发送大量bajillion,然后开始插入再次返回Thread.sleep区块,好像已中断的标志已被重置。

  5. 制作人Thread.currentThread().interrupt();中的InterruptException是我在其他人的代码中看到过的内容,但如果我将其包括在内,它似乎没有做任何事情。

  6. 这些是我很困惑的小事。主要问题是如何在消费者获得所需产品之后尽可能有效地关闭生产者,尽可能地关闭生产者。

1 个答案:

答案 0 :(得分:1)

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

出于Thread.currentThread().interrupt()的目的,请参阅http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html。这样做是个坏主意

catch( InterruptedException ignore) {}

while循环中。链接文章中的更多细节。