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 }