015.2Condiction接口
Condiction对象能够让线程等待,也能够唤醒相应的线程,通过下面方法,具体看代码:
await();
signal();
signalAll();
使用步骤:
1)创建锁
2)通过锁拿到Condiction对象
3)Condiction对象等待后,就需要别人唤醒才会继续执行该进程
例子代码:
1 import java.util.concurrent.locks.Condition; 2 import java.util.concurrent.locks.Lock; 3 import java.util.concurrent.locks.ReentrantLock; 4 5 public class NewProducerConsumerCondition 6 { 7 8 public static void main(String[] args) 9 { 10 Resource r = new Resource(); 11 12 //2,创建线程任务。 13 Producer pro = new Producer(r); 14 Consumer con = new Consumer(r); 15 16 //3,创建线程。 17 Thread t1 = new Thread(pro); 18 Thread t2 = new Thread(pro); 19 Thread t3 = new Thread(con); 20 Thread t4 = new Thread(con); 21 22 t1.start(); 23 t2.start(); 24 t3.start(); 25 t4.start(); 26 } 27 28 } 29 30 class Resource{ 31 private String name; 32 private int count = 1; 33 private final Lock lock = new ReentrantLock(); 34 private Condition produce = lock.newCondition(); 35 private Condition consume = lock.newCondition(); 36 private boolean flag = false; 37 public void set(String name) 38 { 39 lock.lock(); 40 try{ 41 while(flag){ 42 try{produce.await();}catch(Exception e){} //Condiction对象等待 43 } 44 this.name = name + count; 45 count += 1; 46 System.out.println(Thread.currentThread().getName()+"-----生产者-------"+this.name); 47 flag = true; 48 consume.signalAll(); 49 }finally{ 50 lock.unlock(); 51 } 52 } 53 54 public void out() 55 { 56 lock.lock(); 57 try{ 58 while(!flag){ 59 try{consume.await();}catch(Exception e){} 60 } 61 System.out.println(Thread.currentThread().getName()+"-----消费者-------"+this.name); 62 flag = false; 63 produce.signalAll(); 64 }finally{ 65 lock.unlock(); 66 } 67 } 68 } 69 70 class Producer implements Runnable 71 { 72 private Resource r ; 73 // 生产者一初始化就要有资源,需要将资源传递到构造函数中。 74 Producer(Resource r) 75 { 76 this.r = r; 77 } 78 public void run() 79 { 80 while(true) 81 { 82 r.set("大白兔奶糖"); 83 } 84 } 85 } 86 87 class Consumer implements Runnable 88 { 89 private Resource r ; 90 // 消费者一初始化就要有资源,需要将资源传递到构造函数中。 91 Consumer(Resource r) 92 { 93 this.r = r; 94 } 95 public void run() 96 { 97 while(true) 98 { 99 r.out(); 100 } 101 } 102 103 }
class BoundedBuffer { final Lock lock = new ReentrantLock();// 锁 final Condition notFull = lock.newCondition(); // 生产 final Condition notEmpty = lock.newCondition(); // 消费 final Object[] items = new Object[100];// 存储商品的容器。 int putptr/* 生产者使用的角标 */, takeptr/* 消费者使用的角标 */, count/* 计数器 */; /* 生产者使用的方法,往数组中存储商品 */ public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) // 判断计数器是否已到数组长度。满了。 notFull.await();// 生产就等待。 items[putptr] = x; // 按照角标将商品存储到数组中 if (++putptr == items.length) // 如果存储的角标到了数组的长度,就将角标归零。 putptr = 0; ++count;// 计数器自增。 notEmpty.signal();// 唤醒一个消费者 } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) // 如果计数器为0,说明没有商品,消费者等待。 notEmpty.await(); Object x = items[takeptr]; // 从数组中通过消费者角标获取商品。 if (++takeptr == items.length) // 如果消费的角标等于了数组的长度,将角标归零。 takeptr = 0; --count;// 计数器自减。 notFull.signal();// 唤醒生产者。 return x; } finally { lock.unlock(); } } }