Java度线程——生产消费问题

2019-05-22 06:28:44来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折


/*
JDK1.4版本:生产者,消费者。
多生产者,多消费者的问题。
if判断标记,只有一次,会导致不该运行的线程运行了。出现了数据错误的情况。
while判断标记,解决了线程获取执行权后,是否要运行!

notify:只能唤醒一个线程,如果本方唤醒了本方,没有意义。而且while判断标记+notify会导致死锁。
notifyAll解决了本方线程一定会唤醒对方线程的问题。

该方法虽然可行,但是效率并非最好,JDK1.4版本已经无法解决效率问题,需要JDK1.5版本才能解决
*/

 1 class Resource
 2 {
 3     private String name;
 4     private int count = 1;
 5     private boolean flag = false;
 6     public synchronized void set(String name)//  
 7     {
 8         while(flag)
 9             try{this.wait();}catch(InterruptedException e){}//   t1    t0
10         
11         this.name = name + count;//烤鸭1  烤鸭2  烤鸭3
12         count++;//2 3 4
13         System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);//生产烤鸭1 生产烤鸭2 生产烤鸭3
14         flag = true;
15         notifyAll();
16     }
17 
18     public synchronized void out()//  t3
19     {
20         while(!flag)
21             try{this.wait();}catch(InterruptedException e){}    //t2  t3
22         System.out.println(Thread.currentThread().getName()+"...消费者........"+this.name);//消费烤鸭1
23         flag = false;
24         notifyAll();
25     }
26 }
27 
28 class Producer implements Runnable
29 {
30     private Resource r;
31     Producer(Resource r)
32     {
33         this.r = r;
34     }
35     public void run()
36     {
37         while(true)
38         {
39             r.set("烤鸭");
40         }
41     }
42 }
43 
44 class Consumer implements Runnable
45 {
46     private Resource r;
47     Consumer(Resource r)
48     {
49         this.r = r;
50     }
51     public void run()
52     {
53         while(true)
54         {
55             r.out();
56         }
57     }
58 }
59 
60 
61 
62 public class  ProducerConsumerDemo
63 {
64     public static void main(String[] args)
65     {
66         Resource r = new Resource();
67         Producer pro = new Producer(r);
68         Consumer con = new Consumer(r);
69 
70         Thread t0 = new Thread(pro);
71         Thread t1 = new Thread(pro);
72         Thread t2 = new Thread(con);
73         Thread t3 = new Thread(con);
74         t0.start();
75         t1.start();
76         t2.start();
77         t3.start();
78 
79     }
80 }
JDK1.4


--------------------------------------------------------------------------------------------------------------------------
/*
jdk1.5以后将同步和锁封装成了对象。
并将操作锁的隐式方式定义到了该对象中,
将隐式动作变成了显示动作。

Lock接口: 出现替代了同步代码块或者同步函数。将同步的隐式锁操作变成现实锁操作。
同时更为灵活。可以一个锁上加上多组监视器。
lock():获取锁。
unlock():释放锁,通常需要定义finally代码块中。


Condition接口:出现替代了Object中的wait notify notifyAll方法。
            将这些监视器方法单独进行了封装,变成Condition监视器对象。
            可以任意锁进行组合。
await();
signal();
signalAll();

该版本能够提高效率,因为我们不必唤醒所有对象,做多余的判断;

当然在这我们可以指定对象唤醒,在生产者生产完毕后,只需要唤醒消费者中的对象即可;反义,在消费者消费完毕后,我们只需指定唤醒生产者即可。

故我们的效率有所提升,因为不需要做多余的判断。
*/

  1 import java.util.concurrent.locks.*;
  2 
  3 class Resource
  4 {
  5     private String name;
  6     private int count = 1;
  7     private boolean flag = false;
  8 
  9 //    创建一个锁对象。
 10     Lock lock = new ReentrantLock();
 11 
 12     //通过已有的锁获取该锁上的监视器对象。
 13 //    Condition con = lock.newCondition();
 14 
 15     //通过已有的锁获取两组监视器,一组监视生产者,一组监视消费者。
 16     Condition producer_con = lock.newCondition();
 17     Condition consumer_con = lock.newCondition();
 18 
 19     
 20     public  void set(String name)//  t0 t1
 21     {
 22         lock.lock();
 23         try
 24         {
 25             while(flag)
 26 //            try{lock.wait();}catch(InterruptedException e){}//   t1    t0
 27             try{producer_con.await();}catch(InterruptedException e){}//   t1    t0
 28         
 29             this.name = name + count;//烤鸭1  烤鸭2  烤鸭3
 30             count++;//2 3 4
 31             System.out.println(Thread.currentThread().getName()+"...生产者5.0..."+this.name);//生产烤鸭1 生产烤鸭2 生产烤鸭3
 32             flag = true;
 33 //            notifyAll();
 34 //            con.signalAll();
 35             consumer_con.signal();
 36         }
 37         finally
 38         {
 39             lock.unlock();
 40         }
 41         
 42     }
 43 
 44     public  void out()// t2 t3
 45     {
 46         lock.lock();
 47         try
 48         {
 49             while(!flag)
 50 //            try{this.wait();}catch(InterruptedException e){}    //t2  t3
 51             try{cousumer_con.await();}catch(InterruptedException e){}    //t2  t3
 52             System.out.println(Thread.currentThread().getName()+"...消费者.5.0......."+this.name);//消费烤鸭1
 53             flag = false;
 54 //            notifyAll();
 55 //            con.signalAll();
 56             producer_con.signal();
 57         }
 58         finally
 59         {
 60             lock.unlock();
 61         }
 62         
 63     }
 64 }
 65 
 66 class Producer implements Runnable
 67 {
 68     private Resource r;
 69     Producer(Resource r)
 70     {
 71         this.r = r;
 72     }
 73     public void run()
 74     {
 75         while(true)
 76         {
 77             r.set("烤鸭");
 78         }
 79     }
 80 }
 81 
 82 class Consumer implements Runnable
 83 {
 84     private Resource r;
 85     Consumer(Resource r)
 86     {
 87         this.r = r;
 88     }
 89     public void run()
 90     {
 91         while(true)
 92         {
 93             r.out();
 94         }
 95     }
 96 }
 97 
 98 
 99 
100 class  ProducerConsumerDemo2
101 {
102     public static void main(String[] args)
103     {
104         Resource r = new Resource();
105         Producer pro = new Producer(r);
106         Consumer con = new Consumer(r);
107 
108         Thread t0 = new Thread(pro);
109         Thread t1 = new Thread(pro);
110         Thread t2 = new Thread(con);
111         Thread t3 = new Thread(con);
112         t0.start();
113         t1.start();
114         t2.start();
115         t3.start();
116 
117     }
118 }
JDK1.5

 


原文链接:https://www.cnblogs.com/CSAH/p/10886669.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:Model、ModelMap、ModelAndView的使用和区别

下一篇:Spring Cloud(7):Zuul自定义过滤器和接口限流