某面试题,实现一个生产者——消费者模型

题目:采用多线程技术,通过wait/notify,设计实现一个符合生产者和消费者问题的程序,对某一个对象(枪膛)进行操作,其最大容量是20颗子弹,生产者线程是一个压入线程,它不断向枪膛中压入子弹,消费者线程是一个射出线程,它不断从枪膛中射出子弹。

public class Test {

    public Queue<Integer> gun = new LinkedList<Integer>(); // 枪
public final int maxCount = 20; // 枪里面最多上20发子弹 public final int maxbulletCount = 200; // 枪里面最多上20发子弹
public final int[] bullets = new int[maxbulletCount];
private int pos = 0; public Test() {
Random r = new Random();
for (int i = 0; i < maxbulletCount; i++) {
bullets[i] = r.nextInt(1000);
}
} private int getBullet() {
return pos < maxbulletCount ? bullets[pos++] : -1;
} class Producer implements Runnable {
@Override
public void run() {
while (true) {
synchronized (gun) {
try {
if(gun.size() == maxCount){
System.out.println("*********** 枪膛已经上满子弹");
gun.wait();
} else {
int i = getBullet();
if (i == -1) {
System.out.println("*********** 子弹已经用完");
Thread.interrupted();
} else {
gun.add(i);
System.out.println("*********** 子弹" + i + "上膛 枪里面还有" + gun.size() + "颗子弹"); try {
Thread.sleep(199);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} gun.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} } class Consumer implements Runnable {
public void run() {
while (true) {
synchronized (gun) {
try {
if( gun.size() == 0 ){
System.out.println("*********** 枪没子弹了 ");
gun.wait();
} else {
Integer bullet = gun.poll();
System.out.println("*********** 使用子弹" + bullet + ", 枪里面还有" + gun.size() + "颗子弹"); try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
} gun.notifyAll();
} catch (Exception e) {
e.printStackTrace();
}
}
}
} } public static void main(String[] args) {
Test t = new Test();
Thread p = new Thread(t.new Producer());
Thread c = new Thread(t.new Consumer());
p.start();
c.start();
}
}

值得注意的是:notify并不释放锁,只是唤醒其他线程来竞争锁,当synchronized代码执行完才释放锁。一般建议使用notifyAll,不使用notify,因为notify容器造成信号丢失,并不一定能通知到我们想要告知的线程。

wait/notify的更多相关文章

  1. Thread Object wait() notify()基本

    package com.thread.test.thread; import java.util.ArrayDeque; import java.util.Queue; import java.uti ...

  2. 如何在 Java 中正确使用 wait, notify 和 notifyAll(转)

    wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视.本文对这些关键字的使用进行了描述. 在 Java 中可以用 wait ...

  3. java多线程wait notify join

    wait notify 几个注意点: wait 与 notify/notifyAll 方法必须在同步代码块中使用,即要先对调用对象加锁. 当线程执行wait()时,会把当前的锁释放,然后让出CPU,进 ...

  4. 【Java并发系列02】Object的wait()、notify()、notifyAll()方法使用

    一.前言 对于并发编程而言,除了Thread以外,对Object对象的wati和notify对象也应该深入了解其用法,虽然知识点不多. 二.线程安全基本知识 首先应该记住以下基本点,先背下来也无妨: ...

  5. 【多线程】java多线程 测试例子 详解wait() sleep() notify() start() join()方法 等

    java实现多线程,有两种方法: 1>实现多线程,继承Thread,资源不能共享 2>实现多线程  实现Runnable接口,可以实现资源共享 *wait()方法 在哪个线程中调用 则当前 ...

  6. #研发中间件介绍#异步消息可靠推送Notify

    郑昀 基于朱传志的设计文档 最后更新于2014/11/11 关键词:异步消息.订阅者集群.可伸缩.Push模式.Pull模式 本文档适用人员:研发   电商系统为什么需要 NotifyServer? ...

  7. 线程同步以及 yield() wait()和notify()、notifyAll()

    1.yield() 该方法与sleep()类似,只是不能由用户指定暂停多长时间,并且yield()方法只能让同优先级的线程有执行的机会. 2.wait()和notify().notifyAll() 这 ...

  8. java 多线程之wait(),notify,notifyAll(),yield()

    wait(),notify(),notifyAll()不属于Thread类,而是属于Object基础类,也就是说每个对像都有wait(),notify(),notifyAll()的功能.因为都个对像都 ...

  9. wait、notify、sleep、interrupt对比分析

    对比分析Java中的各个线程相关的wait().notify().sleep().interrupt()方法 方法简述 Thread类 sleep:暂停当前正在执行的线程:(类方法) yield:暂停 ...

  10. java中的wait(),notify(),notifyAll(),synchronized方法

    wait(),notify(),notifyAll()三个方法不是Thread的方法,而是Object的方法.意味着所有对象都有这三个方法,因为每个对象都有锁,所以自然也都有操作锁的方法了.这三个方法 ...

随机推荐

  1. XCode9: iPhone is busy: Preparing debugger support for iPhone

    这个好像是等一阵子就可以了 参考链接

  2. J2SE-鸡汤

    前言 终于开始学java了,心里免不了的开心,总是听老乡说他们公司搞java开发,用的什么什么框架,说的自己都有点眼馋了,但是根据自己的性格,不了解它,肯定不会就去用它的.所以在学习框架之前,java ...

  3. 【bzoj4800】: [Ceoi2015]Ice Hockey World Championship dfs

    [bzoj4800]: [Ceoi2015]Ice Hockey World Championship N<=40所以如果直接dfs背包会TLE 考虑Meet-in-the-middle 如果把 ...

  4. BZOJ1096 [ZJOI2007]仓库建设(斜率优化)

    题目背景 小B的班级数学学到多项式乘法了,于是小B给大家出了个问题:用编程序来解决多项式乘法的问题. 题目描述 L公司有N个工厂,由高到底分布在一座山上. 工厂1在山顶,工厂N在山脚. 由于这座山处于 ...

  5. Spark大数据处理 之 RDD粗粒度转换的威力

    在从WordCount看Spark大数据处理的核心机制(2)中我们看到Spark为了支持迭代和交互式数据挖掘,而明确提出了内存中可重用的数据集RDD.RDD的只读特性,再加上粗粒度转换操作形成的Lin ...

  6. 5分钟构建无服务器敏感词过滤后端系统(基于FunctionGraph)

    摘要:开发者通过函数工作流,无需配置和管理服务器,以无服务器的方式构建应用,便能开发出一个弹性高可用的后端系统.托管函数具备以毫秒级弹性伸缩.免运维.高可靠的方式运行,极大地提高了开发和运维效率,减小 ...

  7. win10系统重装

    问题描述 win10开启热点网卡坏了,没折腾好.然后把系统网卡折腾坏了. 所以重装了系统,写下我的环境从零到晚上的过程 1安装系统 用WePE安装win10,镜像采用:cn_windows_10_en ...

  8. pytorch实现squeezenet

    squeezenet是16年发布的一款轻量级网络模型,模型很小,只有4.8M,可用于移动设备,嵌入式设备. 关于squeezenet的原理可自行阅读论文或查找博客,这里主要解读下pytorch对squ ...

  9. 深浅copy 和 集合

    1 对于赋值运算,就是共同指向一个内存地址.将一个值赋予一个变量,那么它的内存地址同时也赋予了他,如果值是不可变类型,改变值,就会产生一个新值和新内存地址,如果值是可变类型那么内存地址不会变. s1 ...

  10. SprimgMVC学习笔记(五)—— Controller方法返回值

    一.返回ModelAndView controller方法中定义ModelAndView对象并返回,对象中可添加model数据.指定view. /** * 查询商品列表 * @return */ @R ...