java实现生产者消费者

Posted by LeoSpring on April 22, 2019

第一个版本以syncronized和Object的wait()、notify()/notifyAll()方法实现唤醒。

public class TestProductCustomer {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
//        list.add(1);
//        list.add(2);
        Product p = new Product("product",list);
        Customer c = new Customer("customer", list);
        p.start();
        c.start();
    }
}

class Product extends Thread {

    List<Integer> list = new ArrayList<>();

    public Product(String name, List<Integer> list) {
        super(name);
        this.list = list;
    }

    @Override
    public void run() {
        while (true) {
            //加锁
            synchronized (list) {
                //必须使用while循环
                while (list.size() == 10) {
                    try {
                        //生产者满了 线程等待
                        System.out.println("生产已满,等待消费");
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                int i = new Random().nextInt();
                System.out.println("生产者:" + i);
                list.add(i);
                生成成功,通知其他线程可以消费
                list.notifyAll();
                try {
                    //休眠50毫秒观察效果
                    TimeUnit.MILLISECONDS.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

class Customer extends Thread {

    List<Integer> list = new ArrayList<>();

    public Customer(String name, List<Integer> list) {
        super(name);
        this.list = list;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (list) {
                while ((list.size() == 0)) {
                    try {
                        System.out.println("生产余额不足,等待");
                        list.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                Integer i = list.remove(0);
                System.out.println("消费者消费:" + i + " 剩余数量:" + list.size());
                list.notifyAll();
                try {
                    TimeUnit.MILLISECONDS.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

第二个版本使用Lock的condition条件锁实现

public class TestProductCustomer2 {
    public static void main(String[] args) {
        Lock lock = new ReentrantLock();
        Condition condition1 = lock.newCondition();
        Condition condition2 = lock.newCondition();
        List<Integer> list = new ArrayList<>();
        Product2 p = new Product2("product",list,lock,condition1,condition2);
        Customer2 c = new Customer2("customer",lock,condition1,condition2,list);
        p.start();
        c.start();
    }
}

class Product2 extends Thread {

    List<Integer> list = new ArrayList<>();
    Lock lock = null;
    Condition condition1 = null;
    Condition condition2 = null;

    public Product2(String name, List<Integer> list, Lock lock, Condition condition1, Condition condition2) {
        super(name);
        this.list = list;
        this.lock = lock;
        this.condition1 = condition1;
        this.condition2 = condition2;
    }

    @Override
    public void run() {
        while (true) {
            lock.lock();
            while (list.size() == 10) {
                try {
                    System.out.println("生产已满,等待消费");
                    condition1.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            int i = new Random().nextInt();
            System.out.println("生产者:" + i);
            list.add(i);
            condition2.signal();
            try {
                TimeUnit.MILLISECONDS.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lock.unlock();
        }
    }
}

class Customer2 extends Thread {
    Lock lock = null;
    Condition condition1 = null;
    Condition condition2 = null;

    List<Integer> list = new ArrayList<>();

    public Customer2(String name, Lock lock, Condition condition1, Condition condition2, List<Integer> list) {
        super(name);
        this.lock = lock;
        this.condition1 = condition1;
        this.condition2 = condition2;
        this.list = list;
    }

    @Override
    public void run() {
        while (true) {
            lock.lock();
            while ((list.size() == 0)) {
                try {
                    System.out.println("余额不足,等待生产");
                    condition2.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            Integer i = list.remove(0);
            System.out.println("消费者消费:" + i + " 剩余数量:" + list.size());
            condition1.signal();
            try {
                TimeUnit.MILLISECONDS.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lock.unlock();
        }
    }
}