wait(), notify(),sleep详解
单单在概念上理解清楚了还不够,需要在实际的例子中进行测试才能更好的理解。对Object.wait(),Object.notify()的应用最经典的例子,应该是三线程打印ABC的问题了吧,这是一道比较经典的面试题,题目要求如下:
建立三个线程,A线程打印10次A,B线程打印10次B,C线程打印10次C,要求线程同时运行,交替打印10次ABC。这个问题用Object的wait(),notify()就可以很方便的解决。代码如下:
public class MyThreadPrinter implements Runnable{
private String name;
private Object prev;
private Object self;
private MyThreadPrinter(String name,Object prev,Object self){
this.name = name;
this.prev = prev;
this.self = self;
}
public void run(){
int count = 10;
while(count>0){
synchronized(prev){
synchronized (self) {
System.out.println("正在打印的是:"+name+"---"+count);
count--;
self.notify();
}
if(count>0){
try {
prev.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args){
Object a = new Object();
Object b = new Object();
Object c = new Object();
MyThreadPrinter pa = new MyThreadPrinter("A", c, a);
MyThreadPrinter pb = new MyThreadPrinter("B", a, b);
MyThreadPrinter pc = new MyThreadPrinter("C", b, c);
new Thread(pa).start();
new Thread(pb).start();
new Thread(pc).start();
}
}
public void run(){
int count = 10;
while(count>0){
synchronized(prev){
synchronized (self) {
System.out.println("正在打印的是:"+name+"---"+count);
count--;
try{
Thread.sleep(1);
}
catch (InterruptedException e){
e.printStackTrace();
}
self.notify();
}
if(count>0){
try {
prev.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
运行后的打印结果就变成了ACBACB了。为了避免这种与JVM调度有关的不确定性。需要让A,B,C三个线程以确定的顺序启动,最终代码如下:
public class MyThreadPrinter implements Runnable{
private String name;
private Object prev;
private Object self;
private MyThreadPrinter(String name,Object prev,Object self){
this.name = name;
this.prev = prev;
this.self = self;
}
public void run(){
int count = 10;
while(count>0){
synchronized(prev){
synchronized (self) {
System.out.println("正在打印的是:"+name+"---"+count);
count--;
try{
Thread.sleep(1);
}
catch (InterruptedException e){
e.printStackTrace();
}
self.notify();
}
if(count>0){//防止最后的对象b在wait()之后没有线程来唤醒了
try {
prev.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args){
Object a = new Object();
Object b = new Object();
Object c = new Object();
MyThreadPrinter pa = new MyThreadPrinter("A", c, a);
MyThreadPrinter pb = new MyThreadPrinter("B", a, b);
MyThreadPrinter pc = new MyThreadPrinter("C", b, c);
try{
new Thread(pa).start();
Thread.sleep(1);
new Thread(pb).start();
Thread.sleep(1);
new Thread(pc).start();
Thread.sleep(1);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
参考资料:
wait(), notify(),sleep详解的更多相关文章
- JAVA wait(), notify(),sleep详解
转自: http://blog.csdn.net/zyplus 在JAVA中,是没有类似于PV操作.进程互斥等相关的方法的.JAVA的进程同步是通过synchronized()来实现的,需要说明的是, ...
- Java多线程学习之wait、notify/notifyAll 详解
1.wait().notify/notifyAll() 方法是Object的本地final方法,无法被重写. 2.wait()使当前线程阻塞,前提是 必须先获得锁,一般配合synchronized 关 ...
- Java多线程之wait、notify/notifyAll 详解,用wait 和notifyAll 以及synchronized实现阻塞队列,多线程拓展之ReentrantLock与Condition
前言:这几天看了很多关于多线程的知识,分享一波.(但是目前接触的项目还未用到过,最多用过线程池,想看线程池 请看我之前的博客) 关于基本的理论等 参考如下: https://www.cnblogs.c ...
- virtIO前后端notify机制详解
2016-11-15 本来这是在前端驱动后期分析的,但是这部分内容比较多,且分析了后端notify前端的机制,所以还是单独拿出一节分析比较好! 还是拿网络驱动部分做案例,网络驱动部分有两个队列,(忽略 ...
- Java精通并发-notify方法详解及线程获取锁的方式分析
wait(): 在上一次https://www.cnblogs.com/webor2006/p/11404521.html中对于无参数的wait()方法的javadoc进行了解读,而它是调用了一个参数 ...
- virtio前端驱动详解
2016-11-08 前段时间大致整理了下virtIO后端驱动的工作模式以及原理,今天就从前端驱动的角度描述下目前Linux内核代码中的virtIO驱动是如何配合后端进行工作的. 注:本节代码参考Li ...
- 201709019工作日记--sleep、wait、notify的使用详解
1. sleep()和wait()的区分 (1)这两个方法来自不同的类分别是,sleep来自Thread类,wait来自Object类. sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在 ...
- Android Notification 详解(一)——基本操作
Android Notification 详解(一)--基本操作 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Notification 文中如有纰 ...
- Android Notification 详解——基本操作
Android Notification 详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天项目中有用到 Android 通知相关的内容,索性把 Android Notificatio ...
随机推荐
- Using SYSTEM.MOUSE_ITEM In Oracle Forms
If the mouse is in an item, SYSTEM.MOUSE_ITEM represents the name of that item as a CHAR value.For e ...
- [SAP ABAP开发技术总结]报表事件
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- canvas背景透明
var can=document.getElementById("canv"); c=can.getContext("2d"); c.globalAlpha=. ...
- 《易货》Alpha版本发布说明
一.引言 本说明描述了校淘1.0版本的已经实现的主要功能,对运行环境的要求,以及目前软件所具有的一些问题和限制. 二.主要功能 本软件面向的是在校大学生,方便大学生将自己闲置的物品以二手商品的形式发布 ...
- C# 上传RAR文件 解压 获取解压后的文件名称
此方法适用于C盘windows文件夹中有WinRAR.exe文件 if (fileExt.ToUpper() == ".RAR") { string zpath = Server. ...
- Maven核心概念之依赖,聚合与继承
一.依赖 我们项目中依赖的jar包可以通过依赖的方式(dependencies元素下添加dependency子元素)引入. <dependency> <groupId>juni ...
- (六)动手写第一个shell
1.编辑器.编译器.运行方法(脚本的3种执行方法)(1)shell程序是文本格式的,只要是文本编辑器都可以.但是因为我们的shell是要在linux系统下运行的,所以换行符必须是'\n',而windo ...
- you don't have permission to view it 解决
the file couldn't be opened because you don't have permission to view it 简单设置下面的选项即可,不要谢我啊! change ...
- Java 获取各时区时间,获取当前时间到格林威治时间1970年01月01日00时00分00秒的秒数
格林威治时间即UTC/GMT时间,1970年01月01日00时00分00秒(即UTC+8的北京时间1970年01月01日08时00分00秒)计算代码如下: /** * 获取指定时间到格林威治时间的秒数 ...
- Js_动画显示背景图片
jAni是一个可以动画显示背景图片的jQuery插件.这个插件基本上是GIF动画的一个替代品,但是他有他的好处.所有浏览器都支持GIF形式的动画格式,而且也不需要额外的javaScript代码和标记. ...