Java-初步认识-第十四章-线程间通信-多生产者多消费者问题-JDK1.5解决办法

一.

在1.5版本中,将原先的形式进行了改变,但是功能并没有任何变化,那么这么做的原因是什么?

以前,我们一个锁上只有一组监视器,这组监视器既监视着生产者,又监视着消费者。这组监视器能将生产者和消费者全都wait,也能将生产者和消费者全都唤醒。或者notify也行,它也能将其中一条线程唤醒,而其中一条不能确定是谁,有可能是本方,也可能是对方。

现在我们的线程进行了分类,一组负责生产,一组负责消费。我们希望生产者能够唤醒消费者,消费者唤醒生产者。如果搞两个监视器,一组监视生产者,一组监视消费者,这就靠谱了

以前怎么弄的,生产者得具备一个锁,消费者得具备另一个锁,因为一个锁只能有一个监视器,现在一个锁上有多个监视器。现在我们四个线程用的是同一把锁,但是监视器不一样,是两个监视器,一个监视生产者,一个监视消费者。生产这边拿的是消费的唤醒,唤醒的就是消费的线程。

如果是两个锁,那么生产只能用于生产,消费只能用于消费(这是说的以前的做法),它俩可以同时运行,就会导致问题。

而我们现在生产里面在操作的时候,消费是不能动的,这叫同一个锁。

producer_con生产者监视器,consumer_con消费者监视器。

一个锁上挂着多个监视器。

package t4;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 
 * @author 高小硕
 * jdk1.5以后将同步和锁封装成对象
 * 
 * 并将操作锁的隐式方式定义到了该对象中。
 * 将隐式动作变成了显示动作
 * 
 * Lock接口:出现替代了同步代码块或者同步函数。将同步的隐式锁操作变成现实锁操作
 * 同时更为灵活。可以一个锁上加上多组监视器。
 * 
 * lock():获取锁
 * unlock():释放锁,通常需要定义在finall代码块中
 * 
 * Condition接口:出现替代了Object中的wait  notify notifyAll方法
 * 
 * 			将这些监视器方法单独进行了封装,变成Condition监视器对象。
 *			 可以任意锁进行组合。
 *await();
 *signal();
 *signalAll();
 * 
 *
 */
class Resource
{
    private String name;
    private int count=1;
    private boolean flag=false;
//创建一个锁对象
    
    Lock lock = new ReentrantLock();
    //通过已有的锁获取该锁上的监视器对象
    //使用两个监视器
    Condition producer_con = lock.newCondition();
    Condition consumber_con = lock.newCondition();

    
    public  void set(String name)
    {	
    	lock.lock();
        try
        {
        	 while(flag)
//            try{wait();}catch(InterruptedException e){}
              try{producer_con.await();}catch(InterruptedException e){}
  
        this.name=name+count;
        count++;//2 3 4
        System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);
        flag=true;
        consumber_con.signal();//唤醒对方的线程
        }
        finally {
			lock.unlock();
		}

    }
    public  void out()
    {	
    	lock.lock();
    	try {
    		while(!flag)
//            try{wait();}catch(Exception e){}
            try{consumber_con.await();}catch(InterruptedException e){}

        System.out.println(Thread.currentThread().getName()+".....消费者......"+this.name);
        flag=false;
        producer_con.signal();
    	}
    	finally {
			lock.unlock();
		}
    }
}


class Producer implements Runnable
{
    private Resource r;
    public Producer(Resource r)
    {
        this.r=r;
    }
    public void run()
    {
        while(true)
        {
            r.set("烤鸭");
        }
    }
}
class Consumer implements Runnable
{
    private Resource r;
    public Consumer(Resource r)
    {
        this.r=r;
    }
    public void run()
    {
        while(true)
        {
            r.out();
        }
    }
}
public class LockProducerConsumer
{
    public static void main(String[] args)
    {
        Resource r=new Resource();

        Producer pro=new Producer(r);
        Consumer con=new Consumer(r);

        Thread t1=new Thread(pro);
        Thread t2=new Thread(pro);
        Thread t3=new Thread(con);
        Thread t4=new Thread(con);

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

    }
}

猜你喜欢

转载自blog.csdn.net/fighting_future/article/details/80397711