黑马程序员技术交流社区

标题: 多线程——生产者和消费者的改进-Lock接口 [打印本页]

作者: 水蛭31    时间: 2015-6-19 11:41
标题: 多线程——生产者和消费者的改进-Lock接口
多线程——生产者和消费者的改进-Lock接口
在上一个代码中,存在一个bug, 就是notifyAll(), 可能会将本方的线程也给唤醒, 如何才能让他不换醒呢?
接口中Lock,特点是替代了synchronized,比使用synchronized方法和语句可获得更广泛的锁定操作。
首先:synchronized,开锁解锁都是隐式的, 而lock就可以一目了然的看到,他是显示的,
并且可以支持多个相关的Condition对象。
Condition把wait,notify,notifyAll,替代,因此可以将代码改进:
  1. /*
  2. 用synchronized,开锁解锁是隐式的, 但是用lock , 就可以一目了然了,
  3. 显式的,
  4. */
  5. import java.util.concurrent.locks.*;
  6. class Resource
  7. {
  8.         private String name;
  9.         private int count=1;
  10.         private boolean flag=false;
  11.         private Lock lock=new ReentrantLock();//多态, 创建一个锁对象,
  12.         private Condition condition_pro=lock.newCondition();//创建condition的对象
  13.         private Condition condition_con=lock.newCondition();
  14.         public void set(String name)throws InterruptedException{
  15.                 //将同步的语句变成了两个方法lock(),unlock().
  16.                 lock.lock();//调用lock()方法,获取了一个锁
  17.                 //用if判断, 数据错误, while循环,全部等待, 不是活着的, 冻结了
  18.                 try
  19.                 {
  20.                         while(flag){
  21.                                 condition_pro.await();
  22.                         }
  23.                         this.name=name+"....."+count++;
  24.                         System.out.println(Thread.currentThread().getName()+"....生产...."+this.name);
  25.                         flag=true;       
  26.                         condition_con.signal();
  27.                 }
  28.                 finally{
  29.                         lock.unlock();//解锁,这句话必须执行的。
  30.                 }
  31.                
  32.         }
  33.         public void out()throws InterruptedException{
  34.                 lock.lock();
  35.                 try
  36.                 {
  37.                         while(!flag){
  38.                         condition_con.await();
  39.                         }
  40.                         System.out.println(Thread.currentThread().getName()+"........消费........"+this.name);
  41.                         flag=false;
  42.                         condition_pro.signal();
  43.                 }
  44.                 finally{
  45.                         lock.unlock();
  46.                 }
  47.         }
  48. }
  49. class Producer implements Runnable
  50. {       
  51.         private Resource res;
  52.         Producer(Resource res){
  53.                 this.res=res;
  54.         }
  55.         public void run()
  56.         {
  57.                 while(true){
  58.                         try
  59.                         {
  60.                                 res.set("+商品+");
  61.                         }
  62.                         catch (InterruptedException e)
  63.                         {
  64.                         }       
  65.                 }
  66.         }
  67. }
  68. class Consumer implements Runnable
  69. {
  70.         private Resource res;
  71.         Consumer(Resource res){
  72.                 this.res=res;
  73.         }
  74.         public void run(){
  75.                 while(true){
  76.                         try
  77.                         {
  78.                                 res.out();
  79.                         }
  80.                         catch (InterruptedException e)
  81.                         {
  82.                         }
  83.                 }
  84.         }
  85. }
  86. class  ThreadProCus2
  87. {
  88.         public static void main(String[] args)
  89.         {
  90.                 Resource res=new Resource();
  91.                 Producer pro=new Producer(res);
  92.                 Consumer con=new Consumer(res);
  93.                 Thread t1=new Thread(pro);
  94.                 Thread t2=new Thread(pro);
  95.                 Thread t3=new Thread(con);
  96.                 Thread t4=new Thread(con);
  97.                 t1.start();
  98.                 t2.start();
  99.                 t3.start();
  100.                 t4.start();
  101.         }
  102. }
复制代码
注明:

private Lock lock=new ReentrantLock();//多态, 创建一个锁对象
private Condition condition_pro=lock.newCondition();//创建condition的对象
private Condition condition_con=lock.newCondition();
并且可以指定某个锁的condition的对象。
优点:
JDK1.5后提供了显式的锁机制和显式的等待唤醒操作机制,同时把等待唤醒机制封装了对象,,一个锁可以对应多个condition,
而以前只能有一个wait , condition ,
本例中,实现了本方只唤醒对方的操作。








欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2