生产者--消费者模式
1、示例:
java">class Resource{
private String name;
private int count = 1;
private Boolean flag = false;
public synchronized void set(String name){
if(flag)
try {
this.wait();//this代表调用函数线程
} catch (InterruptedException e) {}
this.name = name+"__ " + count++;
System.out.println(Thread.currentThread().getName()+ "......生产者" + this.name);
flag = true;
this.notifyAll();
}
public synchronized void show(){
if(!flag)
try {
this.wait();
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread().getName()+"消费者"+ this.name);
flag = false;
this.notifyAll();
}
}
//定义生产类Producter,生产商品
class Producter implements Runnable{
private Resource r;
Producter(Resource r){
this.r = r;
}
public void run(){
while(true){
r.set("商品");
}
}
}
//定义消费者类Customer,消费商品
class Customer implements Runnable{
private Resource r;
Customer(Resource r){
this.r = r;
}
public void run(){
while(true){
r.show();
}
}
}
分析:
- 多个生产者、消费者定义使用while判断标记
原因:让被唤醒的线程再次判断标记
- 定义中使用notifyAll
原因: 因为需要唤醒对方线程,如果使用notify容易出现值唤醒本方线程的情况,导致线程中所有线程都处于等待状态
2.JDK5中提供多线程解决方案
- 将同步synchronized替换成lock操作
- 将object中的wait/notify/notifyALl替换成condtion对象
- 该对象可以通过lock锁进行获取
示例:
java">package unit18;
import java.util.concurrent.locks.*;
class Resources{
private String name;
private int count = 1;
private Boolean flag = false;
private Lock lock = new ReentrantLock();//定义Lock类
private Condition condition_pro = lock.newCondition();
private Condition condition_con = lock.newCondition();
public void set(String name)throws InterruptedException{
lock.lock();//添加锁
try{
while(flag){
condition_pro.wait();//生产者调用线程等待
}
this.name = name+"__ " + count++;
System.out.println(Thread.currentThread().getName()+ "......生产者" + this.name);
flag = true;
condition_pro.signal(); //唤醒消费者线程
}catch(Exception e){}
finally{
lock.unlock();//解锁
}
}
public synchronized void show()throws InterruptedException{
lock.lock();
try{
while(!flag){
condition_con.wait();
}
System.out.println(Thread.currentThread().getName()+"消费者"+ this.name);
flag = false;
condition_con.signal();//唤醒生产者线程
}catch(Exception e){}
finally{
lock.unlock();
}
}
}
class Producters implements Runnable{
private Resources r;
Producters(Resources r){
this.r = r;
}
public void run(){
while(true){
try {
r.set("商品");
} catch (InterruptedException e) {
}
}
}
}
class Customers implements Runnable{
private Resources r;
Customers(Resources r){
this.r = r;
}
public void run(){
while(true){
try {
r.show();
} catch (InterruptedException e) {
}
}
}
}
public class ProducterCustomerTest2 {
public static void main(String[] args) {
Resources r = new Resources();
Producters pro = new Producters(r);
Customers cus = new Customers(r);
Thread t1 = new Thread(pro);
// Thread t2 = new Thread(pro);
// Thread t3 = new Thread(cus);
Thread t2 = new Thread(cus);
t1.start();
// t2.start();
// t3.start();
t2.start();
}
}