zoukankan      html  css  js  c++  java
  • 生产者消费者 java.util.concurrent.lock包

    package com.mozq.thread.producer2;
    
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    /**
     *     当使用等待时
     *     如果用if会造成,线程被唤醒时不管条件是否满足,都会执行任务代码。产生错误。
     *     改用while,每次线程被唤醒时会进行条件判断,是否满足。但是产生了死锁问题。
     *     1.通过使用notifyAll而不是notify方法来解决死锁。
     *     单生产者和单消费者不会因使用while发生死锁,因为,线程池中只有 一个另一方的线程,notify方法必然会唤醒另一方的线程。
     *     多生产者和多消费者的等待集中有生产方和消费方的线程,notify方法可能会唤醒本方线程而不是另一方,造成 死锁。
     *     
     *     Condition对象可以为表示锁的一个等待集,一个锁可以产生多个Condition对象也就是等待集。并对它们分别进行操作。
     *     针对多生产者和多消费者,我们可以分别为生产者和消费者创建一个等待集,并在唤醒时,调用另一方等待集的通知,确保唤醒的是另一方线程。避免了死锁。
     * 
     * @author jie
     *
     */
    class Resource{
        private String name = null;
        private int count = 0;
        private boolean set = false;
        private Lock lock = new ReentrantLock();
        private Condition producer = lock.newCondition();
        private Condition consumer = lock.newCondition();
        
        public void set(String name) {
            lock.lock();
            try {
                //如果已经存在资源,等待
                while(set) {
                    try {
                        producer.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //没有资源就创建
                count++;
                this.name = name + count;
                System.out.println(Thread.currentThread().getName() + "生产。"+ this.name);
                set = true;
                //同时消费者消费
                consumer.signal();
            }finally {
                lock.unlock();
            }
        }
        
        public void out() {
            lock.lock();
            try {
                //如果没有产品,等待
                while(!set) {
                     try {
                         consumer.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //有就消费
                System.out.println(Thread.currentThread().getName() + "消费。。。。。"+ this.name);
                set = false;
                //通知生产者生产
                producer.signal();
            } finally {
                lock.unlock();
            }
        }
    }
    
    class Input implements Runnable{
        private Resource r;
        public Input(Resource r) {
            this.r = r;
        }
    
        @Override
        public void run() {
            while(true) {
                r.set("烤鸡");
            }
        }
        
    }
    class Output implements Runnable{
        private Resource r;
        public Output(Resource r) {
            this.r = r;
        }
        
        @Override
        public void run() {
            while(true) {
                r.out();
            }
        }
        
    }
    
    public class ProducerConsumerDemo {
        public static void main(String[] args) {
            //创建资源
            Resource r = new Resource();
            //创建任务
            Input in = new Input(r);
            Output out = new Output(r);
            //创建线程
            Thread t0 = new Thread(in);
            Thread t1 = new Thread(in);
            Thread t2 = new Thread(out);
            Thread t3 = new Thread(out);
            //开启线程
            t0.start();
            t1.start();
            t2.start();
            t3.start();
        }
    }
  • 相关阅读:
    二分图最大匹配的König定理及其证明
    HDOJ 2389 Rain on your Parade
    HDOJ 1083 Courses
    HDOJ 2063 过山车
    POJ 1469 COURSES
    UESTC 1817 Complete Building the Houses
    POJ 3464 ACM Computer Factory
    POJ 1459 Power Network
    HDOJ 1532 Drainage Ditches
    HDU 1017 A Mathematical Curiosity
  • 原文地址:https://www.cnblogs.com/mozq/p/10411089.html
Copyright © 2011-2022 走看看