Java生产者/消费者线程——通过等待停止线程执行

Java生产者/消费者线程——通过等待停止线程执行,java,android,multithreading,producer-consumer,Java,Android,Multithreading,Producer Consumer,我的Android应用程序中有两个线程,它们实际上处于生产者/消费者关系中;生产者线程(线程的子类)用对象填充缓冲区,消费者线程(AsyncTask的子类)在该缓冲区上操作。从Java guarded locks并发教程中,我了解到我可以使用“第三方”线程来协调此交换,但理想情况下,我希望能够通过调用wait来关闭使用者线程本身,因为它唯一真正的任务是在生产者填充缓冲区后对其进行操作。然后,生产者将通过调用notify或notifyAll唤醒它,直到生产者完全填充完缓冲区。为了方便这一点,我分别

我的Android应用程序中有两个线程,它们实际上处于生产者/消费者关系中;生产者线程(线程的子类)用对象填充缓冲区,消费者线程(AsyncTask的子类)在该缓冲区上操作。从Java guarded locks并发教程中,我了解到我可以使用“第三方”线程来协调此交换,但理想情况下,我希望能够通过调用wait来关闭使用者线程本身,因为它唯一真正的任务是在生产者填充缓冲区后对其进行操作。然后,生产者将通过调用notify或notifyAll唤醒它,直到生产者完全填充完缓冲区。为了方便这一点,我分别为我的消费者和生产者进行了以下配置:

Consumer.java

public class Consumer extends AsyncTask<Object,Integer,Object>{
private String TAG = "Consumer";
private String SUBCLASS_TAG = "";
private String FUNCTION_TAG = "";
private int UUID = MasterSemaphore.getAndIncrementUuidTracker();

public synchronized void getMonitorForNotification(){
FUNCTION_TAG = "::getMonitorForNotification";
while(MasterSemaphore.getIsBufferingMap().get(UUID)){
try {
Log.i(TAG+SUBCLASS_TAG+FUNCTION_TAG, "about to wait...");
  wait();
} catch (InterruptedException e) {
  e.printStackTrace();
  }
}
FUNCTION_TAG = "::getMonitorForNotification";
Log.i(TAG+SUBCLASS_TAG+FUNCTION_TAG, "Received notification!");
}

@Override
protected Object doInBackground(Object... bgTaskResources) {
Producer hProducer = (Producer)bgTaskResources[0];
//The next call is supposed to freeze this thread's execution via an invocation
//of wait-- see the Producer::populateBuffer(...) method
hProducer.populateBuffer(5,this); 
//...handle other AsyncTask callbacks
就这样。。。所以我们要开始了

externalTaskCaller.getMonitorForNotification();
但永远也够不着

Log.i(TAG+SUBCLASS_TAG+FUNCTION_TAG, "just acquired a monitor lock on 
externalCaller"+externalTaskCaller.toString()+", hopefully");

我的等待通知实现有什么问题?是一个“第三方”对象,类似于链接教程中的DROP对象,需要协调生产者/消费者交换吗?

我会考虑使用<代码>阻塞队列< /代码>。您的消费者将在队列上执行
take()
,而生产者将执行
put()
。没有等待,代码格式不好,很难理解。这显然不符合我见过的等待/通知模式。我建议@Gray使用一个固定的同步队列,比如j.u.c.BlockingQueue。需要注意的一点是,您已经在两个类之间传播了锁定行为,这通常是一个坏迹象。将同步的共享队列分解为一个单独的类,该类在一个地方处理所有锁定/同步。(你可能会发现你已经重新实现了一个BQ)正如@Gray所指出的那样,使用
阻塞队列会更好。是我之前发布的一个示例。BlockingQueue看起来很合理,谢谢。我仍然想理解应该如何实现wait notify习惯用法,以促进我在上面寻找的行为,如果可能的话——在读了一点JVM监视器模型之后,听起来就像是这种行为(工作线程在收到状态更改通知之前暂停执行,然后使用依赖于所述状态更改的代码恢复)可能不可能,或者至少可能不可取。我是否应该提出一个关于Java monitor并发模型的新问题,或者它是否足够相关,可以在这里回答?
externalTaskCaller.getMonitorForNotification();
Log.i(TAG+SUBCLASS_TAG+FUNCTION_TAG, "just acquired a monitor lock on 
externalCaller"+externalTaskCaller.toString()+", hopefully");