我的Android应用程序中有两个线程,它们有效地处于生产者/消费者关系中;生产者线程(Thread的子类)使用对象填充缓冲区,而使用者线程(AsyncTask的子类)在该缓冲区上运行。从Java保护锁并发教程here我收集到我可以使用'第三方'线程来协调这个交换,但理想情况下我希望能够通过调用来关闭消费者线程本身等待,因为它的唯一真正任务是在生成器填充后对缓冲区进行操作。然后,只有当生产者完成填充缓冲区时,生产者才会通过调用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
Producer.java
//..snip
public synchronized int populateBuffer(int numElements, Consumer externalTaskCaller){
TAG = "Producer"
SUBCLASS_TAG = "";
FUNCTION_TAG = "::populateBuffer";
//First set the bufferingMap over the external caller's UUID to true
MasterSemaphore.getIsBufferingMap().put(externalTaskCaller.getUUID(), true);
Log.i(TAG+SUBCLASS_TAG+FUNCTION_TAG, "just set "+externalTaskCaller.getUUID()+" Key in
the bufferingMap to true");
//Next acquire the monitor of the external caller, and tell it to wait for notification
externalTaskCaller.getMonitorForNotification();
Log.i(TAG+SUBCLASS_TAG+FUNCTION_TAG, "just acquired a monitor lock on
externalCaller"+externalTaskCaller.toString()+", hopefully");
int elementsProduced = 0;
for (int i=0;i<numElements;i++){
mvElemVector.add(new Element());
Log.i(TAG+SUBCLASS_TAG+FUNCTION_TAG, "just created element number "+i+" of
"+numElements);
elementsProduced++;
}
if(externalTaskCaller != null){
MasterSemaphore.getIsBufferingMap().put(externalTaskCaller.getUUID(), false);
Log.i(TAG+SUBCLASS_TAG+FUNCTION_TAG, "just set "+externalTaskCaller.getUUID()+" Key
in the bufferingMap to false since our buffer writing is done");
externalTaskCaller.notifyAll();
Log.i(TAG+SUBCLASS_TAG+FUNCTION_TAG, "just notified the external caller
"+externalTaskCaller.toString());
}
return threadsProduced;
}
//..snip
当我对此功能运行单元测试时,我看到的结果(实际上只是创建并启动Producer线程,然后创建并执行Consumer任务)仅返回日志条目:
01-02 09:01:53.530: I/Producer::populateBuffer(21932): just set 0 Key in the
bufferingMap to true
01-02 09:01:53.530:I/Consumer::getMonitorForNotification(21932): about to wait...
就是这样......所以我们要进入
externalTaskCaller.getMonitorForNotification();
但永远不会到达
Log.i(TAG+SUBCLASS_TAG+FUNCTION_TAG, "just acquired a monitor lock on
externalCaller"+externalTaskCaller.toString()+", hopefully");
我的wait-notify实施有什么问题?是否是协调生产者/消费者交换所需的链接教程中的Drop对象的“第三方”对象?