--------------------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培训、期待与您交流! --------------------