生产者和消费者问题

synchronized版-> wait/notify

juc版->Lock

面试:单例模式、排序算法、生产者和消费者、死锁

生产者和消费者问题 Synchronized版

package org.example.pc;public class A {    public static void main(String[] args) {        Date date = new Date();        new Thread(()->{            for (int i = 0; i {            for (int i = 0; i "+number);//        通知其他线程,我完成了        this.notify();    }    public synchronized void decrement(){        if (number!=1){            try {                this.wait();            } catch (InterruptedException e) {                throw new RuntimeException(e);            }        }        number--;        System.out.println(Thread.currentThread().getName()+"=>"+number);        this.notify();    }}

存在的问题:A、B、C、D四个线程

在线程中判断业务完成唤醒等待应该使用while循环判断,而非if判断,因为if判断值判断一次,在线程中存在一种状态叫虚假唤醒。

JUC版生产者和消费者问题

代码实现

package org.example.pc;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;//判断等待、业务、通知public class Date {    private int number = 0;    private Lock lock = new ReentrantLock();    private Condition inCondition = lock.newCondition();    public void increment() {        try {            lock.lock();            while (number != 0) {                inCondition.await();            }            number++;//        打印加完后的值            System.out.println(Thread.currentThread().getName() + "=>" + number);//        通知其他线程,我完成了            inCondition.signalAll();        } catch (Exception e) {            e.printStackTrace();        } finally {            lock.unlock();        }    }    public void decrement() {        try {            lock.lock();            while (number != 1) {                inCondition.await();            }            number--;            System.out.println(Thread.currentThread().getName() + "=>" + number);            inCondition.signalAll();        } catch (Exception e) {            e.printStackTrace();        } finally {            lock.unlock();        }    }}

Condition 精准的通知唤醒线程

在传统并发编程中,通过notifily唤醒线程后所有线程都是随机获取到资源的,JUC中可以通过Condition来精准的控制要唤醒哪一个线程资源。任何一个新技术的出现都不会只是为了实现之前已有的效果

代码实现

package org.example.pc;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class C {    public static void main(String[] args) {        DateC dateC = new DateC();        new Thread(()->{            for (int i = 0; i {            for (int i = 0; i {            for (int i = 0; i < 10; i++) dateC.plantC();        },"C").start();    }}class DateC {    private int number = 1;    private Lock lock = new ReentrantLock();    private Condition inCondition1 = lock.newCondition();    private Condition inCondition2 = lock.newCondition();    private Condition inCondition3 = lock.newCondition();   public void plantA(){       try {           lock.lock();           while (number!=1){               inCondition1.await();           }           System.out.println(Thread.currentThread().getName());           number=2;           inCondition2.signal();       }catch (Exception e){           e.printStackTrace();       }finally {           lock.unlock();       }   }    public void plantB(){        try {            lock.lock();            while (number!=2){                inCondition2.await();            }            System.out.println(Thread.currentThread().getName());            number=3;            inCondition3.signal();        }catch (Exception e){            e.printStackTrace();        }finally {            lock.unlock();        }    }    public void plantC(){        try {            lock.lock();            while (number!=3){                inCondition3.await();            }            System.out.println(Thread.currentThread().getName());            number=1;            inCondition1.signal();        }catch (Exception e){            e.printStackTrace();        }finally {            lock.unlock();        }    }}