多线程(多生产者,多消费者问题)

//商品
class Resource {
//标记是否已经存在
private boolean flag = false;
private String name;
//商品编号
private int count;


public synchronized void set(String name){
//此处只用while 不能用if 因为线程唤醒后需要进行判断
while(flag)
//商品已经存在 线程等待 释放CPU使用权和锁
try{wait();}catch(Exception e){}
//唤醒所有等待的线程 防止死锁
notifyAll();
flag = true;
count++;
this.name = name;
System.out.println(this.name+" "+this.count);
}

public synchronized void get(){
//此处只用while 不能用if 因为线程唤醒后需要进行判断
while(!flag)
//商品已经存在 线程等待 释放CPU使用权和锁
try{wait();}catch(Exception e){}
//唤醒所有等待的线程 防止死锁
notifyAll();
flag = false;
System.out.println(this.name+" customer"+this.count);
}


}
//生产者
class Producer implements Runnable{
//声明生产的商品
Resource s;
private Producer(){};

Producer(Resource t){
this.s = t;
}
//开始生产
public void run(){
int i = 0;
while(true){
if(i ==0)
s.set("rastduck");
else
s.set("car");
i = (i+1) %2;
}
}
}
//消费者
class Customer implements Runnable{

Resource s;
private Customer(){}
Customer(Resource t){
this.s = t;
}
//开始消费
public void run(){
while(true){
s.get();
}
}

}

class ProducerConsumerDemo{
public static void main (String[] arg){
Resource s = new Resource();

Customer c = new Customer(s);
Producer p = new Producer(s);
//生产线
Thread t1 = new Thread(c);
Thread t2 = new Thread(c);
//消费线
Thread t3 = new Thread(p);
Thread t4 = new Thread(p);

t1.start();
t2.start();
t3.start();
t4.start();

}
}

使用synchronized和锁这种方式不够完美,因为这种方式降低了效率。

所以在jdk1.5之后有了更好的解决方法Lock。

用Lock代替了上文的synchronized,Condition代替了上文的监视器(wait,notify,notifyAll)。

下面是修改后的示例;

import java.util.concurrent.locks.*;
class Resource {
private boolean flag = false;
private String name;
private int count;
//资源锁
Lock lock = new ReentrantLock();
//监视器类
Condition produce_con = lock.newCondition();
Condition customer_con = lock.newCondition();


public void set(String name){
//获取锁
lock.lock();
try{
while(flag)
//生产者线程等待
try{produce_con.await();}catch(Exception e){}
//直接唤醒消费者线程
customer_con.signal();
flag = true;
count++;
this.name = name;
System.out.println(this.name+" "+this.count);
}
finally{
//释放锁,不管try中代码是否报错,记得释放锁。
lock.unlock();
}

}

public void get(){
//获取锁
lock.lock();
try{
while(!flag)
//消费者线程等待
try{customer_con.await();}catch(Exception e){}
//直接唤醒生产者线程
produce_con.signal();
flag = false;
System.out.println(this.name+" customer"+this.count);
}
finally{
//释放锁资源
lock.unlock();
}

}


}
class Producer implements Runnable{
Resource s;
private Producer(){};

Producer(Resource t){
this.s = t;
}
public void run(){
int i = 0;
while(true){
if(i ==0)
s.set("rastduck");
else
s.set("car");
i = (i+1) %2;
}
}
}
class Customer implements Runnable{

Resource s;
private Customer(){}
Customer(Resource t){
this.s = t;
}
public void run(){
while(true){
s.get();
}
}

}

class LockDemo{
public static void main (String[] arg){
Resource s = new Resource();

Customer c = new Customer(s);
Producer p = new Producer(s);
Thread t1 = new Thread(c);
Thread t2 = new Thread(c);
Thread t3 = new Thread(p);
Thread t4 = new Thread(p);

t1.start();
t2.start();
t3.start();
t4.start();

}
}

 

posted @ 2018-07-06 11:27  仙人掌的成长  阅读(399)  评论(0编辑  收藏  举报