多生产者和多消费者---Java程序

/**
 * 这是生产者和消费者程序的升级——多生产者和多消费者
 * @author j
 * 这个程序是有点意思的
 */
/**
多生产者,多消费者
JDK1.5后解决多生产者与消费者问题
java.util.concurrent.locks 包下的
Lock:  
Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作
Condition 
Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,
以便通过将这些对象与任意 Lock 实现组合使用
Condition中的 await  signal  signalAll
使用jdk1.5后这些锁对象与监视对象,最大的一个好处是操作列简单,
并且一个锁可以对应多个监视器,也就是说,我们在生产时,应该唤醒的是
消费线程,消费时应该唤醒的是生产线程。
*/
public class CopyOfProCusTest3 {
public static void main(String[] args) {
Resource r=new Resource();
Production p=new Production(r);
Cus c=new Cus(r);
Thread pThread1=new Thread(p);
Thread pThread2=new Thread(p);
Thread cThread1=new Thread(c);
Thread cThread2=new Thread(c);
pThread1.setName("A");
pThread2.setName("B");
cThread1.setName("C");
cThread2.setName("D");
pThread1.start();
pThread2.start();
cThread1.start();
cThread2.start();
}
}


class Resource{
private String name;
private int num1=1; //生产的序号
private int num2=1; //消费的序号
private int num=0; //产品个数,现在用不着,以后可以扩展,因为现实生活中不可能生产一个就消费一个嘛
//把同步处理放在这里,因为就此题而言,生产和消费是互斥的
//同步只能保证两个线程不打架,即把生产和消费这两个动作"原子化",但是不能使生产线程生产一个,消费线程紧接着消费一个
//为了满足题意,要设置一个变量来控制先生产一个在消费一个,而且还得用wait和notify来让两个线程来通信
private boolean flag=false; //true为生产完,false为消费完,初始状态为false,即还没有生产,需要生产第一个产品
private Lock l=new ReentrantLock();
Condition pc=l.newCondition(); //生产者的监视器
Condition cc=l.newCondition(); //消费者的监视器
public void pro(String name){
l.lock();
try {
while (flag) {
// System.out.println(Thread.currentThread().getName()+" 来了");
try {
pc.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name = name;
System.out.println(Thread.currentThread().getName()+" 生产了第 " + (num1++) + " 个"+name);
flag=true;
cc.signal();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}

catch (RuntimeException e) {
e.printStackTrace();
}
finally{
l.unlock();
}
}
public void cus(){
l.lock();
try {
while (!flag) {
// System.out.println(Thread.currentThread().getName()+" 来了");
try {
cc.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+" 消费了第 "+(num2++)+" 个"+name);
flag=false;
pc.signal();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}

catch (RuntimeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
l.unlock();
}
}
public int getNum1() {
return num1;
}
public void setNum1(int num1) {
this.num1 = num1;
}
public int getNum2() {
return num2;
}
public void setNum2(int num2) {
this.num2 = num2;
}
}


class Production implements Runnable{
//必须引入同一个Resource对象,不然两个线程操作两个对象就不符合生产和消费的题意了
Resource r;
Production(Resource r){
this.r=r;
}
@Override
public void run() {
while (r.getNum1()<500) {
r.pro("面条");
}
}
}


class Cus implements Runnable{
Resource r;
Cus(Resource r){
this.r=r;
}
@Override
public void run() {
while (r.getNum2()<500) {
r.cus();
}
}
}

你可能感兴趣的:(Java语言)