wait/notify
某面试题,实现一个生产者——消费者模型
题目:采用多线程技术,通过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的更多相关文章
- Thread Object wait() notify()基本
package com.thread.test.thread; import java.util.ArrayDeque; import java.util.Queue; import java.uti ...
- 如何在 Java 中正确使用 wait, notify 和 notifyAll(转)
wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视.本文对这些关键字的使用进行了描述. 在 Java 中可以用 wait ...
- java多线程wait notify join
wait notify 几个注意点: wait 与 notify/notifyAll 方法必须在同步代码块中使用,即要先对调用对象加锁. 当线程执行wait()时,会把当前的锁释放,然后让出CPU,进 ...
- 【Java并发系列02】Object的wait()、notify()、notifyAll()方法使用
一.前言 对于并发编程而言,除了Thread以外,对Object对象的wati和notify对象也应该深入了解其用法,虽然知识点不多. 二.线程安全基本知识 首先应该记住以下基本点,先背下来也无妨: ...
- 【多线程】java多线程 测试例子 详解wait() sleep() notify() start() join()方法 等
java实现多线程,有两种方法: 1>实现多线程,继承Thread,资源不能共享 2>实现多线程 实现Runnable接口,可以实现资源共享 *wait()方法 在哪个线程中调用 则当前 ...
- #研发中间件介绍#异步消息可靠推送Notify
郑昀 基于朱传志的设计文档 最后更新于2014/11/11 关键词:异步消息.订阅者集群.可伸缩.Push模式.Pull模式 本文档适用人员:研发 电商系统为什么需要 NotifyServer? ...
- 线程同步以及 yield() wait()和notify()、notifyAll()
1.yield() 该方法与sleep()类似,只是不能由用户指定暂停多长时间,并且yield()方法只能让同优先级的线程有执行的机会. 2.wait()和notify().notifyAll() 这 ...
- java 多线程之wait(),notify,notifyAll(),yield()
wait(),notify(),notifyAll()不属于Thread类,而是属于Object基础类,也就是说每个对像都有wait(),notify(),notifyAll()的功能.因为都个对像都 ...
- wait、notify、sleep、interrupt对比分析
对比分析Java中的各个线程相关的wait().notify().sleep().interrupt()方法 方法简述 Thread类 sleep:暂停当前正在执行的线程:(类方法) yield:暂停 ...
- java中的wait(),notify(),notifyAll(),synchronized方法
wait(),notify(),notifyAll()三个方法不是Thread的方法,而是Object的方法.意味着所有对象都有这三个方法,因为每个对象都有锁,所以自然也都有操作锁的方法了.这三个方法 ...
随机推荐
- Unity自带IAP插件使用(googleplay)
https://blog.csdn.net/ar__ha/article/details/64439872 Unity Services里的Unity IAP对于IOS和GooglePlay的支付用这 ...
- Kubernetes 集群部署(1) -- 自签 TLS 证书
集群功能各模块功能描述: Master节点:主要由四个模块组成,APIServer,schedule, controller-manager, etcd APIServer: APIServer负责对 ...
- 51nod1455(dp)
题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1455 题意: 中文题诶~ 思路: dp 1 <= n, ...
- [51nod1190]最小公倍数之和V2(莫比乌斯反演)
题解 传送门 题解 我是真的不明白这玩意儿是怎么跟反演扯上关系的-- 首先 \[ \begin{align} ans &=b\sum_{d|b}{1\over d}\sum_{i=a}^{b} ...
- 平衡树学习笔记(3)-------Splay
Splay 上一篇:平衡树学习笔记(2)-------Treap Splay是一个实用而且灵活性很强的平衡树 效率上也比较客观,但是一定要一次性写对 debug可能不是那么容易 Splay作为平衡树, ...
- Runtime常用的几个应用场景
Runtime常见的几个应用场景. Runtime常见应用场景 具体应用拦截系统自带的方法调用(Method Swizzling黑魔法) 实现给分类增加属性 实现字典的模型和自动转换 JSPatch替 ...
- 09. ajax跨域问题,同源策略
有三个标签允许跨域加载资源 <img src=“”/> <link href=“”/> <script src=“”> 可以做防盗链图片功能 前端使用jsonp ...
- Ant junitreport with Maven
大家可能都知道在Ant里可以使用junit和junitreport两个task来完成对测试结果生成HTML格式的报告. Maven里的Surefire-report的插件只能对Java测试报告支持的比 ...
- php 中 ?? 和 empty 的 区别
left??right 操作符...当 left 为空时 返回 right ..注意 和 empty 相比 ,空字符,0,'0' 都会返回它本身,而不是 右边的..也就是 当且仅当 没有设置变量或者 ...
- Python中的sin和cos函数
1 第一次使用math.sin()和math.cos(),可是发现结果不对,比如Math.sin(90)=0.893996663600,奇怪? 2 3 一查,原来sin(x) \n\n Ret ...