Lock锁与Condition监视器(生产者与消费者)。

  1 /*生产者与消费者第二次敲,本人表示很郁闷,以后要经常读这个
  2  * Condition 将Object类中的监视器(wait notify notifyAll)分解成不同的对象。例如condition_pro.await():
  3  * condition_com.signal();这两个语句,分别是实例化了*_pro与*_com这两个对象,分别通过调用不同的对线程操作的方法来实现对线程的操作
  4  
  5  
  6  */
  7 
  8 package LockMethod;
  9 import java.util.concurrent.locks.*;//condition,Lock接口都在此包中
 10 class Resource2 
 11 {
 12  private String name;//私有化商品名称
 13  private int commodity=100;//私有化商品编号
 14  private boolean flag=false;//定义一个boolean 型的线程切换标记
 15  private Lock lock=new ReentrantLock();//建立一个锁的对象,多态,父类引用指向子类对象。
 16  Condition condition_pro=lock.newCondition();//实例化一个Condition对象,Condition实例实质是绑定在一个锁上,此语句表示为特定的lock对象获取Condition对象
 17  Condition condition_con=lock.newCondition();
 18  public void set(String name) throws InterruptedException//await()方法抛出异常,API文档写出。set方法为生产者生产商品
 19  { lock.lock();//上锁。目的是同为生产者的t1,t2或者同为消费者的t3T4只能按序执行,不会发生一个商品生产了两次或者被消费了两次
 20   try
 21   { 
 22    while(flag)
 23     condition_pro.await();//await()方法在API文档中有抛出异常,所以在方法上需要throws 一下
 24    this.name=name+commodity++;
 25    System.out.println(Thread.currentThread().getName()+"---producer"+this.name);
 26    flag=true;//改变线程转换标记,使得当前线程再经过一次循环时可以挂那,因为生产一次,消费一次,不能使其再生产一次
 27    condition_con.signal(); //唤醒消费者的线程,使得生产的上品被消费
 28   }
 29   /*catch(Exception e)
 30   {
 31    
 32   }*/
 33   finally//其中代码为必须要执行的语句
 34   {
 35    lock.unlock();//finally中的代码是必须要执行的,解锁,以便让下一个线程可以执行。
 36   }
 37  }
 38  public void out() throws InterruptedException//out方法为消费者消费商品
 39  {
 40   lock.lock();
 41   try
 42   {
 43    while(!flag)//在该线程未被唤醒前,已经通过flag=true;改变了判断值。所以加!使得在消费者线程执行时不指向while中的awake();使其能println()顺利被消费
 44     condition_con.await();
 45    System.out.println(Thread.currentThread().getName()+"---消费者"+this.name);
 46    flag=false;//改变标记,使消费者执行while语句,执行awake(),挂那,等待生产者生产一个商品后在次被唤醒
 47    condition_pro.signal();//唤醒生产者线程
 48   }
 49   finally
 50   {
 51    lock.unlock();//解锁
 52   }
 53  }
 54 }
 55 class Producer2 implements Runnable//实现接口,调用线程要执行的run方法
 56 {
 57  private Resource Res;//私有一个Resource对象
 58  Producer2(Resource Res)//构造函数,传入Resource对象
 59  {
 60   this.Res=Res;
 61  }
 62  public void run()//生产线程所要执行的代码
 63  {
 64   try
 65   {
 66   while(true)//while(true)记住格式,无线循环
 67    Res.set("商品");//调用生产方法,生产产品
 68   }
 69   catch(Exception e)
 70   {
 71    
 72   }
 73  }
 74 }
 75 class Consumer2 implements Runnable
 76 {
 77  private Resource Res;//私有一个Resource对象
 78  Consumer2(Resource Res)//构造函数,传入Resource对象
 79  {
 80   this.Res=Res;
 81  }
 82  public void run()//消费线程所要执行的代码
 83  {
 84   try
 85   {
 86   while(true)
 87    Res.out();//调用消费方法,消费商品
 88   }
 89   catch(Exception e)
 90   {
 91    
 92   }
 93  }
 94 }
 95 
 96  
 97 
 98 public class LockMethod2
 99 {
100  public static void main (String[] args)
101  {
102   Resource r=new Resource();//创建Resource对象
103   
104   Consumer2 con=new Consumer2(r);//分别创建生产者消费者对象,并使其指向Resource对象
105   Producer2 pro=new Producer2(r);
106   
107   Thread t1=new Thread(pro);//创建线程1234,分别指向生产者和消费者。
108   Thread t2=new Thread(pro);
109   Thread t3=new Thread(con);
110   Thread t4=new Thread(con);
111   
112   t1.start();//启动线程
113   t2.start();
114   t3.start();
115   t4.start();
116  }
117 }
原文地址:https://www.cnblogs.com/ruoniao/p/6802446.html