线程同步经典问题:生产者消费者问题
例如:创建一个固定容器,实现add 和 put方法。生产者put,同时消费者get。
问题:固定容量.容器0的时候等待生产者put。容器达到最大数量生产者等待,通知消费者消费

  private final LinkedList<T> linkedList = new LinkedList();
   //固定容器
    private final int MAX = 10;
    private int count=0;
    
    //当前this对象锁
    public synchronized void put(T t) {
        while (linkedList.size() == MAX) { //为什么要用while 而不用 if
            //因为if只判断一次 多个线程的情况下 会存在list容量溢出的情况
            //需要用while判断 循环检查 
            // 
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
        linkedList.add(t);
        ++count;
        //为什么不用 notify 是因为唤醒的线程是不确定的,如果唤醒的是生产者那就 会死锁的状态
        this.notifyAll();

    }

    public synchronized T get() {
        T t = null;
        while (linkedList.size() == 0) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        t = linkedList.removeFirst();
        count--;
        this.notifyAll();//通知生产者生产
        return t;

    }

    public static void main(String[] args) {
        synchronized10<String> stringsynchronized10 = new synchronized10<String>();


        //消费者
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j < 5; j++) {
                    System.out.println(stringsynchronized10.get());
                }
            }, "c" + i).start();

        }

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

         for (int i=0;i<2;i++){

             new Thread(()->{
                 for (int j=0;j<25;j++){
                     stringsynchronized10.put(Thread.currentThread().getName()+" "+j);
                 }
             },"p"+i).start();
         }

    }

另一种实现ReentrantLock实现 Condition可以精确指定,比notifyAll唤醒全部线程效率高

 private LinkedList list = new LinkedList();
    private static int Max = 10;
    private int count = 0;

    private Lock lock = new ReentrantLock();
    //精确指定 可以理解为队列
    Condition product = lock.newCondition();
    Condition consumer = lock.newCondition();

    public void put(Object o) {
        lock.lock();
        try {
            while (list.size() == Max) {
                try {
                    //生产者等待
                    product.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            list.add(o);
            ++count;
            //唤醒消费者
            consumer.signalAll();
        } finally {
            lock.unlock();
        }
    }


    public Object get() {
        Object o = null;
        lock.lock();
        try {
            while (list.size() == 0) {
                try {
                    consumer.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            o = list.removeFirst();
            count--;
            product.signalAll();
        } finally {
            lock.unlock();
        }
        return o;

    }

Redorblack
39 声望0 粉丝

后端菜鸟记录美好生活


引用和评论

0 条评论