OS 多个生产者--消费者间线程通信

class ProducerConsumeerDemo
{
    public static void main(String[] args)
    {
        Resource r = new Resource();
        Producer pro = new Producer(r);
        Consumer con = new Consumer(r);
     Producer pro2 = new Producer(r);
     Consumer con2 = new Consumer(r);
Thread t1
= new Thread(pro); Thread t2 = new Thread(pro2);
     Thread t3 = new Thread(con);
     Thread t4 = new Thread(con2);

t1.start(); t2.start();
//System.out.println(); } } class Resource { private String name; private int count =1 ; private boolean flag = false; public synchronized void set(String name) { while(flag) try{wait();} catch(Exception e){} this.name = name + "---" + count++; System.out.println(Thread.currentThread().getName()+ "--111----Producer" +this.name); flag = true; this.notifyAll(); } public synchronized void out() { while(!flag) try{wait();} catch(Exception e){} System.out.println(Thread.currentThread().getName()+ "--222--Consumer"+this.name); flag = false; this.notifyAll();//this指的是资源对象,锁即资源 } } class Producer implements Runnable { private Resource res; Producer(Resource res) { this.res = res; } public void run() { while(true) res.set("+33"); } } class Consumer implements Runnable { private Resource res; Consumer(Resource res) { this.res = res; } public void run() { while(true) res.out(); } }

t1 t3 ---生产者

t2 t4 ---消费者

针对notify();

当t1生产一个产品后,flag判断完之后 wait一下 (释放锁,cpu) 接着t2 t3 t4 抢夺cpu 如,t2抢到后 也wait了  内存池(存放同一个锁的等待线程)t1 ---> t2

到了t3 消费了一个唤醒了t1 ,t3进入内存池,t4抢到cpu ,也wait了,进入内存池,t1执行,唤醒t2,t2执行,这样产生了生产两个产品,但是第一个被第二个覆盖了。出现ERROR

针对notifyAll()

当t1生产一个产品后,flag判断完之后 wait一下 (释放锁,cpu) 接着t2 t3 t4 抢夺cpu 如,t2抢到后 也wait了  内存池(存放同一个锁的等待线程)t1 ---> t2

到了t3 消费了一个唤醒了所有线程 ,t3进入内存池,t4抢到cpu ,也wait了,进入内存池,t1执行,唤醒所有线程。


JDK1.5 中提供了多线程升级解决方案。
将同步Synchronized替换成显示Lock操作。
将Object中的wait,notify,notifyAll 替换成Condition对象。
该对象可以Lock锁 进行获取。
该示例中,实现了本方只唤醒对方操作。

import java.util.concurrent.locks.*;

class ProducerConsumeerDemo
{
    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(con);
        
        t1.start();
        t2.start();
        //System.out.println();
    }
}

class Resource  
{
    private String name;    
    private int count =1 ;
    private boolean flag = false;
    private Lock lock = new ReentrantLock();
    
    private Condition_pro condition = lock.newCondition();
    private Condition_con condition = lock.newCondition();
    
    public  void set(String name)    throws InterruptedException
    {
        lock.lock();
        try
        {
            while(flag)
                condition_pro.await();
            this.name = name + "---" + count++;
            
            System.out.println(Thread.currentThread().getName()+ "--111----Producer" +this.name);
            flag = true;
            condition_con.signal();
        }
        finally
        {
            lock.unlock();
        }
    }
    
    public  void out()throws InterruptedException
    {
        lock.lock();
        try
        {
            while(!flag)
                condition_con.await();
            System.out.println(Thread.currentThread().getName()+ "--222--Consumer"+this.name);
            flag = false;
            condition_pro.signal();
        }
        finally
        {
            lock.unlock();
        }
    }
}

class Producer implements Runnable
{
    private Resource res;
    
    Producer(Resource res)
    {
        this.res =  res;
    }
    public void run()
    {
        while(true)
            try
            {
                res.set("+33");
            }
            catch(InterruptedException e)
            {
                
            }
    }
}

class Consumer implements Runnable
{
    private Resource res;
    
    Consumer(Resource res)
    {
        this.res =  res;
    }
    public void run()
    {
        while(true)
            try
            {
                res.out();
            }
            catch(InterruptedException e)
            {
                
            }
    }
}
原文地址:https://www.cnblogs.com/WDKER/p/5636584.html