学习到Lock对象啦,用它替换掉synchronized之前两个小例子。
这里等待/唤醒模式,用了Conditon。结合之前的生产者消费者例子,很好理解。
其他类不变,只替换掉MyStack类:
package com.cc.p_c_stack_mutiList2;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Logger;
public class MyStack {
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private List<List<String>> list = new ArrayList<List<String>>();
volatile private boolean noDataFlag = false;
public void push() throws Exception {
lock.lock();
try {
while(list.size() != 0) {
System.out.println("push操作中的:" + Thread.currentThread().getName() + "线程呈wait状态");
condition.await();
}
List<String> next = VinDataList.next();
if(next == null) {
noDataFlag = true;
throw new Exception("生产结束...");
}else {
noDataFlag = false;
list.add(next);
System.out.println(Thread.currentThread().getName()+":push=" + list.size());
}
} catch (Exception e) {
throw new Exception(e.getMessage());
} finally {
condition.signalAll();
lock.unlock();
}
}
public String pop() throws Exception{
lock.lock();
String returnValue = "";
try {
while(list.size() == 0) {
if(noDataFlag) {
throw new Exception("生产结束,消费者也结束->消费者:" + Thread.currentThread().getName() + "结束...");
}
System.out.println("pop操作中的:" + Thread.currentThread().getName() + "线程呈wait状态");
condition.await();
}
returnValue = "" + list.get(0);
list.remove(0);
System.out.println(Thread.currentThread().getName()+":pop=" + list.size());
} catch (Exception e) {
throw new Exception(e.getMessage());
} finally {
condition.signalAll();
lock.unlock();
}
return returnValue;
}
}
运行结果和之前类似。
知识点:
ReentrantLock类的Condition来实现等待/唤醒模式。