--------------------ASP.Net+Android+IOS开发、.Net培训、期待与您交流! --------------------
1. 生产者和消费者
1. 概述
可以有多个消费者,也可以有多个生产者,他们可以一边生产一边消费。
注意:
不管是消费者还是生产者,在生产和消费的前提下,都要判断一下。要用while()循环判断,,如果用if()的话,有可能会发生连续生产或者连续消费,这样就不是一对一了,唤醒的话,就继续执行下面的语句,不再判断的原因。
如果用while()进行判断的话,就可以循环判断,防止前面的情况发生,但是要用signalAll()或notifyAll(),这样可以避免死锁。要是用signal()或notify()的话,会产生死锁。
2.(Lock)
1.5新特性:
Lock和Condition对象。
Lock替换了synchronized,以前锁是看不见的,替换成Lock可以看见的。可以使用Lock(接口)子类对象进行管理锁,lock()方法获取锁,unlock()方法释放锁。
Condition替换了Object类中的wait(),notify(),notifyAll()方法。
Condition对象通过锁来获取,newCondition()方法获取。
Conditioncondition=lock.newCondition()
condition.await()替换了wait()
condition.signal()替换了notify()
condition.signalAll()替换了notifyAll()
3.示例1
这是使用的是一个锁,一个Condition对象
importjava.util.concurrent.locks.Condition; importjava.util.concurrent.locks.Lock; importjava.util.concurrent.locks.ReentrantLock; /*资源*/ public class Resource { private String name; private int count = 1; private boolean flag = false; private Lock lock = new ReentrantLock();//锁 private Condition condition = lock.newCondition();//获取Condition对象 /* 生产 */ public void set(String name) throws InterruptedException { lock.lock(); try { while (flag) condition.await();//线程等待 this.name = name + ":" + (count++); System.out.println(Thread.currentThread().getName() +"生产者生产:" + this.name); this.flag = true; condition.signalAll();//唤醒线程所有 } finally { lock.unlock(); } } publicvoid show() throws InterruptedException { lock.lock(); try{ while(!flag) condition.await();//线程等待 System.out.println(Thread.currentThread().getName()+ "取出第" +this.name ); this.flag= false; condition.signalAll();//唤醒所有线程 }finally { lock.unlock(); } } } /*生产者*/ public class Produce implements Runnable { private Resource re = null; public Produce(Resource re) { this.re = re; } public void run() { while (true) { try { re.set("商品"); Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } } /*消费者*/ public class Customer implements Runnable { private Resource re = null; public Customer(Resource re) { this.re = re; } public void run() { while (true) { try { re.show(); Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } } /*测试类*/ public class Text { public static void main(String[] agrs) { Resource r = new Resource(); new Thread(new Produce(r), "---生产者A----").start(); new Thread(new Produce(r), "---生产者B----").start(); new Thread(new Customer(r), "++消费者1++").start(); new Thread(new Customer(r), "++消费者2++").start(); new Thread(new Customer(r), "++消费者3++").start(); } }
结果:
---生产者A----生产者生产:商品:1
++消费者1++取出第商品:1
---生产者B----生产者生产:商品:2
++消费者3++取出第商品:2
---生产者B----生产者生产:商品:3
++消费者1++取出第商品:3
---生产者A----生产者生产:商品:4
++消费者2++取出第商品:4
---生产者A----生产者生产:商品:5
++消费者3++取出第商品:5
---生产者B----生产者生产:商品:6
++消费者2++取出第商品:6
---生产者A----生产者生产:商品:7
++消费者1++取出第商品:7
---生产者B----生产者生产:商品:8
++消费者2++取出第商品:8
---生产者A----生产者生产:商品:9
++消费者3++取出第商品:9
---生产者B----生产者生产:商品:10
++消费者2++取出第商品:10
---生产者A----生产者生产:商品:11
++消费者3++取出第商品:11
4.示例2
使用的是一个锁,多个Condition对象,不同的Condition对象唤醒的另一个Condition对象,这样就可以不使用的signalAll()方法,
思路:参生产者升生产出商品后,通知消费着(唤醒消费者),消费者消费商品后,通知生产者(唤醒生产者)
只更改资源类就可以,其他的类不用更改。
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /*资源*/ public class Resource { privateString name; privateint count = 1; privateboolean flag = false; privateLock lock = new ReentrantLock();//锁 privateCondition condition_pro = lock.newCondition();//获取生产者的Condition对象 privateCondition condition_cus = lock.newCondition();//获取消费者Condition对象 /* 生产 */ publicvoid set(String name) throws InterruptedException { lock.lock(); try{ while(flag) condition_pro.await();//线程等待(生产者不符合条件) this.name = name + ":" +(count++); System.out.println(Thread.currentThread().getName()+ "生产者生产:" + this.name); this.flag= true; condition_cus.signal();//唤醒消费者 }finally { lock.unlock(); } } public voidshow() throws InterruptedException { lock.lock(); try { while(!flag) condition_cus.await();//线程等待 消费者,不符合条件 System.out.println(Thread.currentThread().getName()+ "取出第" +this.name ); this.flag= false; condition_pro.signalAll();//唤醒生产者 }finally { lock.unlock(); } } }
结果:
---生产者A----生产者生产:商品:1
++消费者1++取出第商品:1
---生产者B----生产者生产:商品:2
++消费者2++取出第商品:2
---生产者A----生产者生产:商品:3
++消费者3++取出第商品:3
---生产者B----生产者生产:商品:4
++消费者2++取出第商品:4
---生产者A----生产者生产:商品:5
++消费者1++取出第商品:5
---生产者B----生产者生产:商品:6
++消费者3++取出第商品:6
---生产者A----生产者生产:商品:7
++消费者1++取出第商品:7
---生产者B----生产者生产:商品:8
++消费者2++取出第商品:8
---生产者A----生产者生产:商品:9
++消费者1++取出第商品:9
---生产者B----生产者生产:商品:10
++消费者3++取出第商品:10
---生产者A----生产者生产:商品:11
++消费者2++取出第商品:11
---生产者B----生产者生产:商品:12
++消费者3++取出第商品:12
---生产者A----生产者生产:商品:13
++消费者3++取出第商品:13
---生产者B----生产者生产:商品:14
++消费者1++取出第商品:14
---生产者B----生产者生产:商品:15
++消费者3++取出第商品:15
---生产者A----生产者生产:商品:16
++消费者2++取出第商品:16
--------------------ASP.Net+Android+IOS开发、.Net培训、期待与您交流!
--------------------