用synchronized或ReentrantLock实现的消费者与生产者

以如下场景为案例:
假设某公司有一个仓库,该仓库只能容下3件货物。
该公司有4名员工,分别为2名进货员(生产者)与2名销售员(消费者)。
每名进货员每次只能进一件货物,每名销售员每次只能卖出一件货物。

  • 以synchronized实现:
public class SynTest {
    public static void main(String[] args) {
        Clerk clerk = new Clerk();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    clerk.sale();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "销售员A").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    clerk.sale();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "销售员B").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    clerk.add();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "进货员A").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    clerk.add();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "进货员B").start();
    }
}

class Clerk {
    private int num = 0;

    public synchronized void add() throws InterruptedException {
        while (num >= 3) {
            System.out.println(Thread.currentThread().getName() + "去看货,发现货物是满的。。。。。。");
            this.wait();
        }
        System.out.println(Thread.currentThread().getName() + "买进了一件,目前还有" + ++num + "件");
        this.notifyAll();
    }

    public synchronized void sale() throws InterruptedException {
        while (num <= 0) {
            System.out.println(Thread.currentThread().getName() + "去看货,发现货物是空的。。。。。。");
            this.wait();
        }
        System.out.println(Thread.currentThread().getName() + "卖出了一件,目前还有" + --num + "件");
        this.notifyAll();
    }
}

控制台输出结果:

销售员A去看货,发现货物是空的。。。。。。
销售员B去看货,发现货物是空的。。。。。。
进货员A买进了一件,目前还有1件
进货员A买进了一件,目前还有2件
进货员A买进了一件,目前还有3件
进货员A去看货,发现货物是满的。。。。。。
销售员B卖出了一件,目前还有2件
销售员B卖出了一件,目前还有1件
销售员B卖出了一件,目前还有0件
销售员B去看货,发现货物是空的。。。。。。
销售员A去看货,发现货物是空的。。。。。。
进货员A买进了一件,目前还有1件
进货员A买进了一件,目前还有2件
进货员A买进了一件,目前还有3件
进货员A去看货,发现货物是满的。。。。。。
销售员A卖出了一件,目前还有2件
销售员A卖出了一件,目前还有1件
销售员A卖出了一件,目前还有0件
销售员A去看货,发现货物是空的。。。。。。
销售员B去看货,发现货物是空的。。。。。。
进货员A买进了一件,目前还有1件
进货员A买进了一件,目前还有2件
进货员A买进了一件,目前还有3件
进货员A去看货,发现货物是满的。。。。。。
进货员B去看货,发现货物是满的。。。。。。
销售员B卖出了一件,目前还有2件
销售员B卖出了一件,目前还有1件
销售员B卖出了一件,目前还有0件
销售员B去看货,发现货物是空的。。。。。。
销售员A去看货,发现货物是空的。。。。。。
进货员B买进了一件,目前还有1件
进货员B买进了一件,目前还有2件
进货员B买进了一件,目前还有3件
进货员B去看货,发现货物是满的。。。。。。
进货员A去看货,发现货物是满的。。。。。。
销售员A卖出了一件,目前还有2件
销售员A卖出了一件,目前还有1件
销售员A卖出了一件,目前还有0件
销售员A去看货,发现货物是空的。。。。。。
销售员B去看货,发现货物是空的。。。。。。
进货员A买进了一件,目前还有1件
进货员B买进了一件,目前还有2件
进货员B买进了一件,目前还有3件
进货员B去看货,发现货物是满的。。。。。。
销售员B卖出了一件,目前还有2件
销售员B卖出了一件,目前还有1件
销售员B卖出了一件,目前还有0件
销售员B去看货,发现货物是空的。。。。。。
销售员A去看货,发现货物是空的。。。。。。
进货员B买进了一件,目前还有1件
进货员B买进了一件,目前还有2件
进货员B买进了一件,目前还有3件
进货员B去看货,发现货物是满的。。。。。。
销售员A卖出了一件,目前还有2件
销售员A卖出了一件,目前还有1件
销售员A卖出了一件,目前还有0件
销售员A去看货,发现货物是空的。。。。。。
销售员B去看货,发现货物是空的。。。。。。
进货员B买进了一件,目前还有1件
进货员B买进了一件,目前还有2件
销售员B卖出了一件,目前还有1件
销售员A卖出了一件,目前还有0件

Process finished with exit code 0

  • 以ReentrantLock实现:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class LockTest {
    public static void main(String[] args) {
        Person person = new Person();

        new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                person.add();
            }
        }, "生产者A").start();

        new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                person.ref();
            }
        }, "消费者A").start();

        new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                person.add();
            }
        }, "生产者B").start();

        new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                person.ref();
            }
        }, "消费者B").start();
    }
}

class Person {
    private volatile int i;
    ReentrantLock lock = new ReentrantLock();
    Condition condition = lock.newCondition();

    public void add() {
        try {
            lock.lock();
            System.out.println(Thread.currentThread().getName() + " 查看仓库,库存为:" + i);
            while (i >= 3) {
                try {
                    System.out.println(Thread.currentThread().getName() + " 发现库存是满的,等待销售......");
                    condition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() + " 进行了进货,现在库存为:" + ++i);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            condition.signalAll();
            lock.unlock();
            System.out.println(Thread.currentThread().getName() + " 离开仓库");
        }
    }

    public void ref() {
        try {
            lock.lock();
            System.out.println(Thread.currentThread().getName() + " 查看仓库,库存为:" + i);
            while (i <= 0) {
                System.out.println(Thread.currentThread().getName() + " 发现库存为空,等待进货......");
                condition.await();
            }
            System.out.println(Thread.currentThread().getName() + " 进行了出货,现在库存为: " + --i);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            condition.signalAll();
            lock.unlock();
            System.out.println(Thread.currentThread().getName() + " 离开仓库");
        }
    }
}

控制台输出:

生产者A 查看仓库,库存为:0
生产者A 进行了进货,现在库存为:1
生产者A 离开仓库
消费者A 查看仓库,库存为:1
消费者A 进行了出货,现在库存为: 0
消费者A 离开仓库
生产者A 查看仓库,库存为:0
生产者A 进行了进货,现在库存为:1
生产者A 离开仓库
消费者A 查看仓库,库存为:1
消费者A 进行了出货,现在库存为: 0
消费者A 离开仓库
生产者B 查看仓库,库存为:0
生产者B 进行了进货,现在库存为:1
生产者B 离开仓库
生产者A 查看仓库,库存为:1
生产者A 进行了进货,现在库存为:2
生产者A 离开仓库
消费者A 查看仓库,库存为:2
消费者A 进行了出货,现在库存为: 1
消费者A 离开仓库
消费者A 查看仓库,库存为:1
消费者A 进行了出货,现在库存为: 0
消费者A 离开仓库
消费者B 查看仓库,库存为:0
消费者B 发现库存为空,等待进货......
生产者B 查看仓库,库存为:0
生产者B 进行了进货,现在库存为:1
生产者B 离开仓库
生产者A 查看仓库,库存为:1
生产者A 进行了进货,现在库存为:2
生产者A 离开仓库
消费者A 查看仓库,库存为:2
消费者A 进行了出货,现在库存为: 1
消费者A 离开仓库
消费者B 进行了出货,现在库存为: 0
消费者B 离开仓库
生产者B 查看仓库,库存为:0
生产者B 进行了进货,现在库存为:1
生产者B 离开仓库
生产者A 查看仓库,库存为:1
生产者A 进行了进货,现在库存为:2
生产者A 离开仓库
消费者B 查看仓库,库存为:2
消费者B 进行了出货,现在库存为: 1
消费者B 离开仓库
生产者B 查看仓库,库存为:1
生产者B 进行了进货,现在库存为:2
生产者B 离开仓库
消费者B 查看仓库,库存为:2
消费者B 进行了出货,现在库存为: 1
消费者B 离开仓库
生产者B 查看仓库,库存为:1
生产者B 进行了进货,现在库存为:2
生产者B 离开仓库
消费者B 查看仓库,库存为:2
消费者B 进行了出货,现在库存为: 1
消费者B 离开仓库
消费者B 查看仓库,库存为:1
消费者B 进行了出货,现在库存为: 0
消费者B 离开仓库

Process finished with exit code 0

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值