多线程之间的通信,等待唤醒机制
概念:多个线程,不同的任务,处理同一资源。
多生产者,多消费者的问题。 if判断标记,只有一次,会导致不该运行的线程运行了。出现了数据错误的情况。 while判断标记,解决了线程获取执行权后,是否要运行!
notify:只能唤醒一个线程,如果本方唤醒了本方,没有意义。而且while判断标记+notify会导致死锁。 notifyAll解决了本方线程一定会唤醒对方线程的问题。
class Resource{ private String name; private int count = 1; private boolean flag = false; public synchronized void set(String name) { while(flag) try{this.wait();}catch(InterruptedException e){} this.name = name + count; count++;//2 3 4 System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name); flag = true; notifyAll(); } public synchronized void out() { while(!flag) try{this.wait();}catch(InterruptedException e){} System.out.println(Thread.currentThread().getName()+"...消费者........"+this.name); flag = false; notifyAll(); }}class Producer implements Runnable{ private Resource r; Producer(Resource r) { this.r = r; } public void run() { while(true) { r.set("烤鸭"); } }}class Consumer implements Runnable{ private Resource r; Consumer(Resource r) { this.r = r; } public void run() { while(true) { r.out(); } }}JDK1.5以后出现了更好的方案,Lock接口替代了synchronized ,Condition接口替代了Object中的监视方法,并将监视器方法封装成了Condition。和以前不同的是,以前一个锁上只能有一组监视器方法。现在,一个Lock锁上可以多组监视器方法对象。可以实现一组负责生产者,一组负责消费者
import java.util.concurrent.locks.*;class Resource{ private String name; private int count = 1; private boolean flag = false;// 创建一个锁对象。 Lock lock = new ReentrantLock(); //通过已有的锁获取该锁上的监视器对象。// Condition con = lock.newCondition(); //通过已有的锁获取两组监视器,一组监视生产者,一组监视消费者。 Condition producer_con = lock.newCondition(); Condition consumer_con = lock.newCondition(); public void set(String name)// t0 t1 { lock.lock(); try { while(flag)// try{lock.wait();}catch(InterruptedException e){} try{producer_con.await();}catch(InterruptedException e){} this.name = name + count; count++;//2 3 4 System.out.println(Thread.currentThread().getName()+"...生产者5.0..."+this.name); flag = true; consumer_con.signal(); } finally { lock.unlock(); } } public void out()// t2 t3 { lock.lock(); try { while(!flag) try{cousumer_con.await();}catch(InterruptedException e){} System.out.println(Thread.currentThread().getName()+"...消费者.5.0......."+this.name); flag = false; producer_con.signal(); } finally { lock.unlock(); } }}class Producer implements Runnable{ private Resource r; Producer(Resource r) { this.r = r; } public void run() { while(true) { r.set("烤鸭"); } }}class Consumer implements Runnable{ private Resource r; Consumer(Resource r) { this.r = r; } public void run() { while(true) { r.out(); } }}