欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-08-11 13:59:33
/*JDK1.4版本:生产者,消费者。多生产者,多消费者的问题。if判断标记,只有一次,会导致不该运行的线程运行了。出现了数据错误的情况。while判断标记,解决了线程获取执行权后,是否要运行!notify:只能唤醒一个线程,如果本方唤醒了本方,没有意义。而且while判断标记+notify会导致死 ......


/*
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.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 }