java两种方法实现生产者消费者问题1:wait notify+synchroized 2:Condition+Renntrantlock

一:2个生产者、10个消费者,自己定义一个容器,实现put、get方法wait notify+synchroized

  • synchronized锁了这个对象,相当于实现了count变量的原子性,操作系统里面pv操作讲过
  • wait方法不仅仅是进入阻塞队列阻塞,而且让出锁
  • 注意1:条件是while不是if       2:notifyall不是notify


import java.util.LinkedList;
public class MyContainer {
    private LinkedList lists = new LinkedList();
    private static final int MAX = 10;
    private static int count = 0;

    private synchronized void put(T t){
        while(count==MAX){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        lists.add(t);
        ++count;
        System.out.println(Thread.currentThread().getName()+"放入一个。 count="+count);
        this.notifyAll();
    }

    private synchronized T get(){
        while(count==0){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        T temp = lists.get(lists.size()-1);
        --count;
        System.out.println(Thread.currentThread().getName()+"拿走一个。 count="+count);
        this.notifyAll();
        return temp;
    }

    public static void main(String[] args) {
        MyContainer container = new MyContainer();
        //开启生产者
        new Thread(()->container.put(new Object()),"thread1").start();
        new Thread(()->container.put(new Object()),"thread2").start();
        for(int i=0;i<10;i++){
            new Thread(()->container.get(),"consumer"+i).start();
        }
    }
}


二:2个生产者、10个消费者,自己定义一个容器,实现put、get方法Condition+Renntrantlock。

比第一种方法有啥优点:
  1. 更容易处理异常。synchronized中间遇到异常会直接释放锁,线程会直接结束,假设一个线程只执行了一半,那就可能产生脏数据。使用Renntrantlock方便控制(lock.lock lock.unlock 碰到异常还可以自己先处理)。
  2. 效率更好。Condition相当于设置了两个等待队列,可以单独唤醒所有的消费者,或者单独唤醒所有的生产者。而第一种方式是唤醒所有的线程。
import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MyContainer2 {
    private LinkedList lists = new LinkedList();
    private static final int MAX = 10;
    private static int count = 0;

    private Lock lock = new ReentrantLock();
    private Condition producer = lock.newCondition();
    private Condition consumer = lock.newCondition();

    private void put(T t){
        try {
            lock.lock();
            while(lists.size()==MAX) {
                producer.await();
            }
            System.out.println(Thread.currentThread().getName()+"放入一个");
            lists.add(t);
            count++;
            consumer.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    private T get(){
        T temp = null;
        try{
            lock.lock();
            while(lists.size()==0){
                consumer.await();
            }
            System.out.println(Thread.currentThread().getName()+"取走一个");
            count--;
            temp = lists.poll();
            producer.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return temp;
    }

    public static void main(String[] args) {
        MyContainer2 container = new MyContainer2();
        //开启生产者
        new Thread(()->container.put(new Object()),"thread1").start();
        new Thread(()->container.put(new Object()),"thread2").start();
        for(int i=0;i<10;i++){
            new Thread(()->container.get(),"consumer"+i).start();
        }
    }
}
111






你可能感兴趣的:(java两种方法实现生产者消费者问题1:wait notify+synchroized 2:Condition+Renntrantlock)