生产者与消费者(夜王与守夜人之间的斗争)

生产者与消费者

生产者消费者问题属于 java 的多线程同步问题,因为涉及多线程之间对同一个资源的访问与操作,java 提供了 wait(),notify(),notifyAll() 等方法来实现多线程之间的同步问题。

生产者

负责对同一资源的生产增加操作。先判断资源数量是否已经达到最大值,如果没有达到则生产资源并调用 notifyAll() 唤醒其他线程;如果有达到则调用对象的 wati() 方法进入阻塞状态,等待被其他线程唤醒。

消费者

负责对同一资源的消费减少操作。先判断资源数量是否已经为 0,如果没有达到则消费资源并调用 notifyAll() 唤醒其他线程;如果有达到则调用对象的 wait() 方法进入阻塞状态,等待被其他线程唤醒。

夜王与守夜人
以权力的游戏里的夜王和守夜人为例,夜王就是一个生产者,负责生产异鬼;而守夜人就是一个消费者,负责消灭异鬼;异鬼就是他们之间共同操作的资源。

示例代码:

package multithreading;

/**
 * 权力的游戏之夜王与守夜人之间的战争
 */
public class GofTest {
    public static void main(String[] args) {
        // 初始化异鬼
        WhiteWalker whiteWalker = new WhiteWalker();
        // 夜王诞生
        Runnable nightKing = new NightKing(whiteWalker);
        // 守夜人出场
        Runnable nightWatch = new NightWatch(whiteWalker);
        // 夜王开始行动
        new Thread(nightKing).start();
        // 守夜人跟上
        new Thread(nightWatch).start();
        // 夜王开始行动
        new Thread(nightKing).start();
        // 守夜人跟上
        new Thread(nightWatch).start();
        // 夜王开始行动
        new Thread(nightKing).start();
        // 守夜人跟上
        new Thread(nightWatch).start();

    }
}

/**
 * 异鬼类
 */
class WhiteWalker {
    /**
     * 数量
     */
    private static Integer count = 0;
    /**
     * 最多 10 个
     */
    private static final Integer MAX = 10;
    /**
     * 北境长城(锁对象)
     */
    private static Object greatWall = new Object();

    /**
     * 生产夜鬼
     */
    public void create() {
        // 北境长城作为锁对象
        synchronized (greatWall) {
            // 判断异鬼是否已经满了
            while (count == MAX) {
                try {
                    // 如果满了,则停止生产,进入阻塞
                    greatWall.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            // 如果没满,则生产
            count++;
            System.out.println(Thread.currentThread().getName() + "夜王生产者生产异鬼,目前共有" + count);
            // 提醒守夜人消费者消费,唤醒所有线程
            greatWall.notifyAll();
        }

    }

    /**
     * 杀异鬼
     */
    public void kill() {
        // 北境长城作为锁对象
        synchronized (greatWall) {
            // 判断异鬼是否已经杀完
            while (count == 0) {
                try {
                    // 杀完则等待,线程阻塞
                    greatWall.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            // 如果没杀完,则杀之
            count--;
            System.out.println(Thread.currentThread().getName() + "守夜人消费者杀异鬼,目前共有" + count);
            // 唤醒所有线程,昭告天下,消灭了异鬼
            greatWall.notifyAll();
        }
    }
}

/**
 * 夜王生产者类,实现 Runnable,负责生产异鬼
 */
class NightKing implements Runnable {

    private WhiteWalker whiteWalker;

    public NightKing(WhiteWalker whiteWalker) {
        this.whiteWalker = whiteWalker;
    }

    @Override
    public void run() {
        // 调用 10 次
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 召唤异鬼
            this.whiteWalker.create();
        }
    }
}

/**
 * 守夜人消费者类,实现 Runnable,负责杀死(消费)异鬼
 */
class NightWatch implements Runnable {

    private WhiteWalker whiteWalker;

    public NightWatch(WhiteWalker whiteWalker) {
        this.whiteWalker = whiteWalker;
    }

    @Override
    public void run() {
        // 调用 10 次
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 消灭异鬼
            this.whiteWalker.kill();
        }
    }
}

测试输出:

Thread-2夜王生产者生产异鬼,目前共有1
Thread-3守夜人消费者杀异鬼,目前共有0
Thread-4夜王生产者生产异鬼,目前共有1
Thread-1守夜人消费者杀异鬼,目前共有0
Thread-0夜王生产者生产异鬼,目前共有1
Thread-5守夜人消费者杀异鬼,目前共有0
Thread-2夜王生产者生产异鬼,目前共有1
Thread-3守夜人消费者杀异鬼,目前共有0
Thread-0夜王生产者生产异鬼,目前共有1
Thread-4夜王生产者生产异鬼,目前共有2
Thread-1守夜人消费者杀异鬼,目前共有1
Thread-5守夜人消费者杀异鬼,目前共有0
Thread-2夜王生产者生产异鬼,目前共有1
Thread-3守夜人消费者杀异鬼,目前共有0
Thread-4夜王生产者生产异鬼,目前共有1
Thread-5守夜人消费者杀异鬼,目前共有0
Thread-0夜王生产者生产异鬼,目前共有1
Thread-1守夜人消费者杀异鬼,目前共有0
Thread-0夜王生产者生产异鬼,目前共有1
Thread-2夜王生产者生产异鬼,目前共有2
Thread-5守夜人消费者杀异鬼,目前共有1
Thread-4夜王生产者生产异鬼,目前共有2
Thread-1守夜人消费者杀异鬼,目前共有1
Thread-3守夜人消费者杀异鬼,目前共有0
Thread-2夜王生产者生产异鬼,目前共有1
Thread-3守夜人消费者杀异鬼,目前共有0
Thread-4夜王生产者生产异鬼,目前共有1
Thread-1守夜人消费者杀异鬼,目前共有0
Thread-0夜王生产者生产异鬼,目前共有1
Thread-5守夜人消费者杀异鬼,目前共有0
Thread-2夜王生产者生产异鬼,目前共有1
Thread-3守夜人消费者杀异鬼,目前共有0
Thread-0夜王生产者生产异鬼,目前共有1
Thread-5守夜人消费者杀异鬼,目前共有0
Thread-4夜王生产者生产异鬼,目前共有1
Thread-1守夜人消费者杀异鬼,目前共有0
Thread-4夜王生产者生产异鬼,目前共有1
Thread-3守夜人消费者杀异鬼,目前共有0
Thread-0夜王生产者生产异鬼,目前共有1
Thread-5守夜人消费者杀异鬼,目前共有0
Thread-2夜王生产者生产异鬼,目前共有1
Thread-1守夜人消费者杀异鬼,目前共有0
Thread-2夜王生产者生产异鬼,目前共有1
Thread-0夜王生产者生产异鬼,目前共有2
Thread-3守夜人消费者杀异鬼,目前共有1
Thread-5守夜人消费者杀异鬼,目前共有0
Thread-4夜王生产者生产异鬼,目前共有1
Thread-1守夜人消费者杀异鬼,目前共有0
Thread-0夜王生产者生产异鬼,目前共有1
Thread-3守夜人消费者杀异鬼,目前共有0
Thread-4夜王生产者生产异鬼,目前共有1
Thread-2夜王生产者生产异鬼,目前共有2
Thread-1守夜人消费者杀异鬼,目前共有1
Thread-5守夜人消费者杀异鬼,目前共有0
Thread-4夜王生产者生产异鬼,目前共有1
Thread-0夜王生产者生产异鬼,目前共有2
Thread-5守夜人消费者杀异鬼,目前共有1
Thread-1守夜人消费者杀异鬼,目前共有0
Thread-2夜王生产者生产异鬼,目前共有1
Thread-3守夜人消费者杀异鬼,目前共有0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值