JAVA实现生产者消费者模式

前言:

貌似很久没更新了,更新一下最近以为自己已经了解,但是还是有一点错误的问题。

sychronized版本

需要注意:sychronized只允许有一个条件,即只有一个wait方法和notify方法,所以无论谁来唤醒,都会唤醒生成者和消费者,值得注意的地方是wait()方法会放弃锁,而sleep不会放弃锁,所以在判断条件处需要使用while来判断,因为当该线程从wait唤醒时,需要再次判断是否满足条件,而不是直接往下执行。

代码:
public class SychronizedDemo {
    private volatile int number=0;
    private final int FULL_NUMBER = 10;
    private Object lock = new Object();


    public static void main(String[] args) {
        SychronizedDemo sychronizedDemo=new SychronizedDemo();
        Thread pro01=new Thread(sychronizedDemo.new Productor());
        pro01.setName("生产者01");
        Thread pro02=new Thread(sychronizedDemo.new Productor());
        pro02.setName("生产者02");
        Thread con01=new Thread(sychronizedDemo.new Consumer());
        con01.setName("消费者01");
        Thread con02=new Thread(sychronizedDemo.new Consumer());
        con02.setName("消费者02");
        pro01.start();
        pro02.start();
        con01.start();
        con02.start();
    }
    class Consumer implements Runnable {
        @Override
        public void run() {
            int i = 0;
            while (i < 10) {
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                synchronized (lock) {
                    while (number <= 0) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    number--;
                    System.out.println(Thread.currentThread().getName() + "消费了一个商品,还剩下" + number+ "个");
                    lock.notifyAll();
                    i++;
                }
            }
        }
    }
    class Productor implements Runnable {
        @Override
        public void run() {
            int i = 0;
            while (i < 10) {
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                synchronized (lock) {
                    while (number >= FULL_NUMBER) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    number++;
                    System.out.println(Thread.currentThread().getName() + "生成了一个商品,此时还有" + number + "个商品");
                    lock.notifyAll();
                    i++;
                }
            }
        }
    }
}

reentrantlock版本

reentrantlock则可以注册多个条件,每次可以只唤醒生成者,或者只唤醒消费者,在唤醒线程方面比较灵活,一样在判断条件处是需要循环判断。值得注意需要手动的获取锁以及手动的注册条件

public class ReentrantLockDemo {
    private volatile int number = 0;
    private final int FULL_NUMBER = 10;
    private ReentrantLock lock = new ReentrantLock();
    Condition isNull = lock.newCondition();
    Condition isFull = lock.newCondition();

    public static void main(String[] args) {
        SychronizedDemo sychronizedDemo = new SychronizedDemo();
        Thread pro01 = new Thread(sychronizedDemo.new Productor());
        pro01.setName("生产者01");
        Thread pro02 = new Thread(sychronizedDemo.new Productor());
        pro02.setName("生产者02");
        Thread con01 = new Thread(sychronizedDemo.new Consumer());
        con01.setName("消费者01");
        Thread con02 = new Thread(sychronizedDemo.new Consumer());
        con02.setName("消费者02");
        pro01.start();
        pro02.start();
        con01.start();
        con02.start();
    }

    class Consumer implements Runnable {
        @Override
        public void run() {
            int i = 0;
            while (i < 10) {
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                lock.lock();
                while (number <= 0) {
                    try {
                        isNull.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                number--;
                System.out.println(Thread.currentThread().getName() + "消费了一个商品,还剩下" + number + "个");
                isFull.notifyAll();
                i++;
                lock.unlock();
            }
        }
    }

    class Productor implements Runnable {
        @Override
        public void run() {
            int i = 0;
            while (i < 10) {
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                lock.lock();
                while (number >= FULL_NUMBER) {
                    try {
                        isFull.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                number++;
                System.out.println(Thread.currentThread().getName() + "生成了一个商品,此时还有" + number + "个商品");
                isNull.notifyAll();
                i++;
                lock.unlock();
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值