WaitNotify-模拟一个生产者,两个消费者交替消费的场景
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class WaitNotify {
private static List<Integer> list = new ArrayList<Integer>();
private static Integer curId = new Integer(1);
private static Integer preId = new Integer(2);
public static void main(String[] args) {
//生产线程
Thread productThread = new Thread(new ProductBiz(list),"productThread");
Thread consumer1Thread = new Thread(new ConsumerBiz(list,curId,preId),"conumser1Thread");
Thread consumer2Thread = new Thread(new ConsumerBiz(list,preId,curId),"conumser2Thread");
productThread.start();
consumer1Thread.start();
consumer2Thread.start();
}
}
class ProductBiz implements Runnable{
private List<Integer> list;
private Random rand = new Random(100);
public ProductBiz(List<Integer> list){
this.list = list;
}
@Override
public void run() {
while(true){
synchronized(list){
try {
list.notifyAll();
list.wait();
if(list.size()<1){
int index = 0, total = rand.nextInt(10);
System.out.print("product("+total+"):");
while (list.size() < total) {
list.add(index++);
System.out.print(" "+ list.get(list.size()-1));
}
System.out.println();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
class ConsumerBiz implements Runnable{
private List<Integer> list;
private Object curId,preId;
public ConsumerBiz(List<Integer> list, Object curId, Object preId){
this.list = list;
this.curId = curId;
this.preId = preId;
}
@Override
public void run() {
while(true){
try {
synchronized (list) {
list.notifyAll();
list.wait();
if (list.size() > 0) {
System.out.println("consumer" + curId + " size=" + list.size() + " 消费:" + list.remove(list.size() - 1));
}
}
//交替控制逻辑,两重锁嵌套
synchronized (preId) {
synchronized (curId) {
curId.notifyAll();
}
preId.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
总结:1,notify/notifyAll,wait 必须获取对象锁时才能调用,否则报异常;
2,notify/notifyAll 必须在 wait之前 否则有风险(程序执行会死锁,导致业务停止)
3,交替提现在同时获取两个信号量的锁之后,一个放行(notify),一个暂停(wait);
同时获取两个信号量的锁,可以用synchronized嵌套的方式;