java中的生产者和消费者的问题
1----使用Java.util.concurrent.locks包中的lock接口取代synchronized,通过ReentrantLock这个已经实现Lock接口的类,
创建ReentrantLock对象lock(private final ReentrantLock lock = new ReentrantLock(); ) ,并通过使用这个对象中的lock()方法让线程获得锁(lock.lock(););
使用unlock();在退出代码块块时释放锁(lock.unlock();),
2----其中while(flag)解决了if(flag)存在的重复生产,使得消费者丢失对其中被覆盖的数据(烧鸡)的读取.但是while会导致死锁,会出现全部线程都被休眠的情况,此时可以将notify ()修改为notifyAll()使得程序被全部唤醒,间接实现相互唤醒,但是由于对同类线程的唤醒时没有意义的,此时,程序的效率降低.
3---解决上一个问题的方法为:使用Java.util.concurrent.locks中的Condition接口,通过对同一个锁创建不同的Condition实例,并使用不同实例调用其各自的await()和signal()方法实现对t0 t1和t2 t3这2组线程的冻结和唤醒管理.从而不再需要每次都全部唤醒造成的效率降低的问题.
1 /* 2 需求:生产者---->消费者 3 资源:烤鸭一只 4 每生产一只,就消费一zhi 5 */ 6 import java.util.concurrent.locks.*; 7 class Resource 8 { 9 private String name; 10 private int count=0; 11 private boolean flag=false; 12 private final ReentrantLock lock = new ReentrantLock(); 13 final Condition cond1 = lock.newCondition(); 14 final Condition cond2 = lock.newCondition(); 15 public void make(String name) 16 { 17 lock.lock(); 18 while(flag) 19 try 20 { 21 cond1.await(); 22 } 23 catch (InterruptedException e) 24 { 25 } 26 27 this.name = name; 28 count++; 29 flag=true; 30 cond2.signal(); 31 System.out.println(Thread.currentThread().getName()+"生产者..."+name+count); 32 lock.unlock(); 33 } 34 public void out() 35 { 36 lock.lock(); 37 while(!flag) 38 try 39 { 40 cond2.await(); 41 } 42 catch (InterruptedException e) 43 { 44 } 45 System.out.println(Thread.currentThread().getName()+"消费者......."+count); 46 flag = false; 47 cond1.signal(); 48 lock.unlock(); 49 } 50 51 } 52 class Producer implements Runnable 53 { 54 Resource r = new Resource(); 55 Producer(Resource r) 56 { 57 this.r = r; 58 } 59 public void run() 60 { 61 while(true) 62 r.make("烤鸭"); 63 } 64 } 65 class Customer implements Runnable 66 { 67 Resource r = new Resource(); 68 Customer(Resource r) 69 { 70 this.r = r; 71 } 72 public void run() 73 { 74 while(true) 75 r.out(); 76 } 77 } 78 class ProducerCustomer 79 { 80 public static void main(String[] args) 81 { 82 //建立资源类 83 Resource r = new Resource(); 84 //建立任务对象 85 Producer pro = new Producer(r); 86 Customer cus = new Customer(r); 87 //建立线程 88 Thread t0 = new Thread(pro); 89 Thread t1 = new Thread(pro); 90 Thread t2 = new Thread(cus); 91 Thread t3 = new Thread(cus); 92 //开启线程 93 t0.start(); 94 t1.start(); 95 t2.start(); 96 t3.start(); 97 98 } 99 }