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 ...
随机推荐
- oracle, create table, insufficient privileges
SQL> exec pro_gz_day_report; ORA-01031: insufficient privileges ORA-06512: at & ...
- GitHub上不错的Android开源项目(三)
收集相关系列资料,自己用作参考,练习和实践.小伙伴们,总有一天,你也能写出 Niubility 的 Android App :-) GitHub上不错的Android开源项目(一):http://ww ...
- NOJ 1063 生活的烦恼
描述 生活的暑假刚集训开始,他要决心学好字典树,二叉树,线段树和各种树,但生活在OJ上刷题的时候就遇到了一个特别烦恼的问题.那当然就是他最喜欢的二二叉树咯!题目是这样的:给你一颗非空的二叉树,然后再给 ...
- Linux中变量#,@,0,1,2,*,$$,$?的含义
$# 是传给脚本的参数个数 $ 是脚本本身的名字 $ 是传递给该shell脚本的第一个参数 $ 是传递给该shell脚本的第二个参数 $@ 是传给脚本的所有参数的列表 $* 是以一个单字符串显示所有向 ...
- spring DI原理
什么是IOC? 也称依赖注入 当一个类,需要另一个类的时候,我们不需要再另一个类里进行创建 对象,spring容器会给我们自动的创建 IOC的实现? 通过一定的技术读取spring.xml文件信息,比 ...
- 初识redis——mac下搭建redis环境
一.redis简介 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合)和zset(有 ...
- (转)http接口测试——Jmeter接口测试实例讲解
http://my.oschina.net/hellotest/blog/512482
- 安装64位版Oracle11gR2后无法启动SQLDeveloper的解决方案(原创) (2016-10-29 下午01:56)
安装64位版Oracle11gR2后发现启动SQL Developer时弹出配置java.exe的路径,找到Oracle自带java.exe后产生的路径"C:\app\用户名\product ...
- python中super关键字的用法
http://python.jobbole.com/86787/ class A: def __init__(self): print "enter A" print ...
- numpy库的常用知识
为什么有numpy这个库呢?准安装的Python中用列表(list)保存一组值,可以用来当作数组使用,不过由于列表的元素可以是任何对象,因此列表中所保存的是对象的指针.这样为了保存一个简单的[1,2, ...