OS 多个生产者--消费者间线程通信
class ProducerConsumeerDemo { public static void main(String[] args) { Resource r = new Resource(); Producer pro = new Producer(r); Consumer con = new Consumer(r);
Producer pro2 = new Producer(r);
Consumer con2 = new Consumer(r); Thread t1 = new Thread(pro); Thread t2 = new Thread(pro2);
Thread t3 = new Thread(con);
Thread t4 = new Thread(con2);
t1.start(); t2.start(); //System.out.println(); } } class Resource { private String name; private int count =1 ; private boolean flag = false; public synchronized void set(String name) { while(flag) try{wait();} catch(Exception e){} this.name = name + "---" + count++; System.out.println(Thread.currentThread().getName()+ "--111----Producer" +this.name); flag = true; this.notifyAll(); } public synchronized void out() { while(!flag) try{wait();} catch(Exception e){} System.out.println(Thread.currentThread().getName()+ "--222--Consumer"+this.name); flag = false; this.notifyAll();//this指的是资源对象,锁即资源 } } class Producer implements Runnable { private Resource res; Producer(Resource res) { this.res = res; } public void run() { while(true) res.set("+33"); } } class Consumer implements Runnable { private Resource res; Consumer(Resource res) { this.res = res; } public void run() { while(true) res.out(); } }
t1 t3 ---生产者
t2 t4 ---消费者
针对notify();
当t1生产一个产品后,flag判断完之后 wait一下 (释放锁,cpu) 接着t2 t3 t4 抢夺cpu 如,t2抢到后 也wait了 内存池(存放同一个锁的等待线程)t1 ---> t2
到了t3 消费了一个唤醒了t1 ,t3进入内存池,t4抢到cpu ,也wait了,进入内存池,t1执行,唤醒t2,t2执行,这样产生了生产两个产品,但是第一个被第二个覆盖了。出现ERROR
针对notifyAll()
当t1生产一个产品后,flag判断完之后 wait一下 (释放锁,cpu) 接着t2 t3 t4 抢夺cpu 如,t2抢到后 也wait了 内存池(存放同一个锁的等待线程)t1 ---> t2
到了t3 消费了一个唤醒了所有线程 ,t3进入内存池,t4抢到cpu ,也wait了,进入内存池,t1执行,唤醒所有线程。
JDK1.5 中提供了多线程升级解决方案。
将同步Synchronized替换成显示Lock操作。
将Object中的wait,notify,notifyAll 替换成Condition对象。
该对象可以Lock锁 进行获取。
该示例中,实现了本方只唤醒对方操作。
import java.util.concurrent.locks.*; class ProducerConsumeerDemo { public static void main(String[] args) { Resource r = new Resource(); Producer pro = new Producer(r); Consumer con = new Consumer(r); Thread t1 = new Thread(pro); Thread t2 = new Thread(con); t1.start(); t2.start(); //System.out.println(); } } class Resource { private String name; private int count =1 ; private boolean flag = false; private Lock lock = new ReentrantLock(); private Condition_pro condition = lock.newCondition(); private Condition_con condition = lock.newCondition(); public void set(String name) throws InterruptedException { lock.lock(); try { while(flag) condition_pro.await(); this.name = name + "---" + count++; System.out.println(Thread.currentThread().getName()+ "--111----Producer" +this.name); flag = true; condition_con.signal(); } finally { lock.unlock(); } } public void out()throws InterruptedException { lock.lock(); try { while(!flag) condition_con.await(); System.out.println(Thread.currentThread().getName()+ "--222--Consumer"+this.name); flag = false; condition_pro.signal(); } finally { lock.unlock(); } } } class Producer implements Runnable { private Resource res; Producer(Resource res) { this.res = res; } public void run() { while(true) try { res.set("+33"); } catch(InterruptedException e) { } } } class Consumer implements Runnable { private Resource res; Consumer(Resource res) { this.res = res; } public void run() { while(true) try { res.out(); } catch(InterruptedException e) { } } }