多线程-线程间通信-多生产者多消费者问题(JDK1.5后Lock,Condition解决办法及开发中代码范例)

  1 package multithread4;
  2 
  3 import java.util.concurrent.locks.Condition;
  4 import java.util.concurrent.locks.Lock;
  5 import java.util.concurrent.locks.ReentrantLock;
  6 
  7 /*同步代码块对于锁的操作是隐式的
  8  * 
  9  * jdk1.5以后将同步和锁封装成了对象。
 10  * 并将操作锁的隐式方式定义到了该对象中,将隐式动作变成了显示动作 
 11  * 
 12  * 
 13  * Lock接口:出现替代了同步代码块或者同步函数。将同步的隐式锁操作变成显式锁操作
 14  * 同时更为灵活,可以一个锁上加上多组监视器。
 15  * lock():获取锁
 16  * unlock():释放锁,通常需要定义finally代码块中。
 17  * 
 18  * Condition接口:出现替代了Object中的wait notify notifyAll方法。
 19  *                 将这些监视器方法单独进行了封装,变成Conditon监视器对象。
 20  *                 可以与任意锁进行组合
 21  * await();
 22  * signal();
 23  * signalAll();
 24  * 
 25  */
 26 
 27 
 28 /*
 29  * 生产者,消费者。
 30  * 
 31  * 多生产者,多消费者的问题。
 32  * 
 33  * if判断标记,只有一次,会导致不该运行的线程运行了。出现了数据错误的情况。
 34  * while判断标记,解决了线程获取执行权后,是否要运行!
 35  * 
 36  * notify:只能唤醒一个线程,如果本方唤醒了本方,没有意义。而且while判断标记+notify会产生死锁
 37  * notifyAll解决了,本方线程一定会唤醒对方线程
 38  * 
 39  * 死锁 四个线程都等待没有被唤醒也是一种情况,悬挂
 40  */
 41 
 42 class Resource2{
 43     private String name;
 44     private int count = 1;
 45     private boolean flag = false;
 46     //创建一个锁对象
 47     Lock lock = new ReentrantLock();
 48     //通过已有的锁获取该锁上的监视器对象。
 49 //    Condition con = lock.newCondition();
 50     
 51     //通过已有的锁获取两组监视器,一组监视生产者,一组监视消费者。 用lock condition解决办法
 52     Condition producer_con = lock.newCondition();
 53     Condition consumer_con = lock.newCondition();
 54     
 55     public void set(String name) {
 56         lock.lock();
 57         try {
 58             /*if*/ while (flag) {
 59                 try {
 60 //                    lock.wait();
 61 //                    con.await();
 62                     producer_con.await();
 63                 } catch (InterruptedException e) {
 64                     
 65                 }
 66             }
 67             this.name = name + count;
 68             count++;
 69             System.out.println(Thread.currentThread().getName()+"..生产者.."+this.name);
 70             flag = true;
 71 //            notify();
 72 //            notifyAll();
 73 //            con.signalAll();
 74             consumer_con.signal();
 75         } finally {
 76             lock.unlock();
 77         }
 78 
 79     }
 80     public void out() {
 81         lock.lock();
 82         try {
 83             /*if*/ while (!flag) {
 84                 try {
 85 //                    con.await();
 86                     consumer_con.await();
 87                 } catch (InterruptedException e) {
 88                     
 89                 }
 90             }
 91             System.out.println(Thread.currentThread().getName()+"..消费者......"+this.name);
 92             flag = false;
 93 //            notify();
 94 //            notifyAll();//为了解决死锁 将其余三个都唤醒
 95 //            con.signalAll();
 96             producer_con.signal();
 97         } finally {
 98             lock.unlock();
 99         }
100 
101 }
102 
103 class Producer implements Runnable{
104     private Resource2 r;
105     public Producer(Resource2 r) {
106         this.r = r;
107     }
108     public void run() {
109         while(true) {
110             r.set("烤鸭");
111         }
112     }
113 }
114 class Consumer implements Runnable{
115     private Resource2 r;
116     public Consumer(Resource2 r) {
117         this.r = r;
118     }
119     public void run() {
120         while(true) {
121             r.out();
122         }
123     }
124 }
125 public class ProducerConsumerDemo2 {
126 
127     public static void main(String[] args) {
128         
129         Resource2 r = new Resource2();
130         Producer pro = new Producer(r);
131         Consumer con = new Consumer(r);
132         
133         Thread t0 = new Thread(pro);
134         Thread t1 = new Thread(pro);
135         Thread t2 = new Thread(con);
136         Thread t3 = new Thread(con);
137         
138         t0.start();
139         t1.start();
140         t2.start();
141         t3.start();
142     }
143 
144 }
ProducerConsumerDemo2

 

posted @ 2021-11-11 16:13  doremi429  阅读(49)  评论(0)    收藏  举报