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

题目:采用多线程技术,通过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. 「ZOJ 1354」Extended Lights Out「高斯消元」

    题意:给定一个\(5\times 6\)的棋盘的\(01\)状态,每次操作可以使它自己和周围四个格子状态取反,求如何操作,输出一个\(01\)矩阵 题解:这题可以通过枚举第一行的状态然后剩下递推来做, ...

  2. Ubuntu 如何为 XMind 添加快速启动方式和图标

    目录 Ubuntu 如何为 XMind 添加快速启动方式和图标 Ubuntu 如何为 XMind 添加快速启动方式和图标 按照教程Ubuntu16.04LTS安装XMind8并创建运行图标进行Xmin ...

  3. 编译安装log4cxx

    1.介绍 Log4cxx是开放源代码项目Apache Logging Service的子项目之一,是Java社区著名的log4j的c++移植版,用于为C++程序提供日志功能,以便开发者对目标程序进行调 ...

  4. c++运算符重载-如何决定作为成员函数还是非成员函数

    The Decision between Member and Non-member The binary operators = (assignment), [] (array subscripti ...

  5. Redis及虚拟机windows两种环境安装配置

    ---恢复内容开始--- Redis  /rae  dis/是一个开源的Key-Value数据库.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链 ...

  6. 使用js实现水波效果

    使用到的工具:jQuery Ripples Plugin 下载安装 git clone https://github.com/sirxemic/jquery.ripples.git 引入jquery, ...

  7. react 拆分组件于组件

    Todolist.js(这是父组件) import React, { Component,Fragment } from 'react'; import './style.css'; import T ...

  8. 分割字符串(C++)

    方案1: 利用"IO流"的概念,即C++中的stream,我们都用过C++中std::iostream中的std::istream与std::ostream 如果你接触过网络编程( ...

  9. ajax加载菊花loading效果

    Ajax异步请求的时候,一般都会利用一个动态的gif小图片来制作一个Ajax Loading,以便增加用户体验. 这里我们可以使用Spin.js,该js脚本压缩后5k,可以不用任何图片,任何外部CSS ...

  10. nginx配置应用

    启动nginxvim /usr/local/lnmp/nginx/conf/nginx.conf mkdir /wwwcd /wwwvim index.html www.westos.orgmkdir ...