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 ...
随机推荐
- Example of Get_File_Name Function in Oracle Forms
Displays the standard open file dialog box where the user can select an existing file or specify a n ...
- Java EE 在网页输出九九乘法表、三角形、菱形
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...
- CUBRID学习笔记 18 sql语句的预处理(类似存储过程)
定义预处理 类似sqlserver的存储过程 语法 PREPARE stmt_name FROM preparable_stmt 说明 PREPARE 关键字 stmt_name 预处理语句的名字 ...
- 分区格式化mkfs
mkfs — build a Linux filesystem 用法举例: mkfs.ext3 /dev/sdb1 #把sdb1格式化为ext3文件系统 也可以写成 mkfs -t ext3 /d ...
- zoj 2107&&hdu 1007最近点对问题
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1107 Quoit Design Time Limit: 5 Seconds ...
- FZU 2215 Simple Polynomial Problem(简单多项式问题)
Description 题目描述 You are given an polynomial of x consisting of only addition marks, multiplication ...
- 《Linux内核设计的艺术》学习笔记(四)默认段和偏移寄存器
参考书籍:<Intel微处理器> 表1 默认的16位段 + 偏移寻址组合 段 偏移量 特殊用途 CS IP 指令地址 SS SP或BP 堆栈地址 DS BX.DI.SI.8位或16位数 数 ...
- css position 绝对定位和相对定位
position:absolute这个是绝对定位:是相对于浏览器的定位.比如:position:absolute:left:20px;top:80px; 这个容器始终位于距离浏览器左20px,距离浏览 ...
- ubuntu_杂
1. 虚拟机安装的 ubuntu 12.04,在关闭了 一段时间不操作就屏保 和 锁屏 之后, 在一段时间之后 虚拟机的屏幕还是变黑了,貌似是 os将 显示器关闭了. 这个相关的设置是在哪里? 相关设 ...
- js分组排序算法, OrderBy
由于项目中需要对数据进行分组排序,类似于sql中 order by column1,column2.... 实现的关键是 分组排序,第一个column1,排序完成之后,对其分组,然后按照column ...