Java度线程——生产消费问题
/*
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 }