美文网首页
java两种方法实现生产者消费者问题1:wait notify+

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

作者: salix_ | 来源:发表于2020-02-06 16:28 被阅读0次

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

    • synchronized锁了这个对象,相当于实现了count变量的原子性,操作系统里面pv操作讲过
    • wait方法不仅仅是进入阻塞队列阻塞,而且让出锁
    • 注意1:条件是while不是if       2:notifyall不是notify
    
    
    import java.util.LinkedList;
    public class MyContainer<T> {
        private LinkedList<T> lists = new LinkedList<T>();
        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<Object> container = new MyContainer<Object>();
            //开启生产者
            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<T> {
        private LinkedList<T> lists = new LinkedList<T>();
        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<Object> container = new MyContainer2<Object>();
            //开启生产者
            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+

          本文链接:https://www.haomeiwen.com/subject/apcuxhtx.html