wait,notify,notifyAll 是定义在Object类的实例方法,用于控制线程状态,在线程协作时,大家都会用到notify()或者notifyAll()方法,其中wait与notify是java同步机制中重要的组成部分,需要结合与synchronized关键字才能使用,在调用一个Object的wait与notify/notifyAll的时候,必须保证调用代码对该Object是同步的,也就是说必须在作用等同于synchronized(object){......}的内部才能够去调用obj的wait与notify/notifyAll三个方法,否则就会报错:java.lang.IllegalMonitorStateException:current thread not owner(意思是因为没有同步,所以线程对对象锁的状态是不确定的,不能调用这些方法)。

wait的目的就在于暴露出对象锁,所以需要保证在lock的同步代码中调用lock.wait()方法,让其他线程可以通过对象的notify叫醒等待在该对象的等该池里的线程。同样notify也会释放对象锁,在调用之前必须获得对象的锁,不然也会报异常。所以,在线程自动释放其占有的对象锁后,不会去申请对象锁,只有当线程被唤醒的时候或者达到最大的睡眠时间,它才再次争取对象锁的权利

主要方法:

(1).wait()
等待对象的同步锁,需要获得该对象的同步锁才可以调用这个方法,否则编译可以通过,但运行时会收到一个异常:IllegalMonitorStateException。调用任意对象的 wait() 方法导致该线程阻塞,该线程不可继续执行,并且该对象上的锁被释放。

(2).notify()
唤醒在等待该对象同步锁的线程(只唤醒一个,如果有多个在等待),注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。调用任意对象的notify()方法则导致因调用该对象的 wait()方法而阻塞的线程中随机选择的一个解除阻塞(但要等到获得锁后才真正可执行)。

(3).notifyAll()
唤醒所有等待的线程,注意唤醒的是notify之前wait的线程,对于notify之后的wait线程是没有效果的。

通过一个实例来看一下实际的效果,开启两个线和,一个线程 打印1到52的数字,一个打印A到Z的字母,要求,打印两个数,打印一个字母,这样交替顺序打印,代码如下:

/**
* create by spy on 2018/6/4
*/
public class ShuZiZiMuThread { public static void main(String[] args) {
Object object = new Object();
shuzi shuzi = new shuzi(object);
zimu zimu = new zimu(object);
Thread t = new Thread(shuzi);
t.setName("shuzi");
Thread t1 = new Thread(zimu);
t1.setName("zimu");
t.start();//数字线程先运行
t1.start();
}
} class shuzi implements Runnable{
private Object object;
//声明类的引用
public shuzi(Object object) {
this.object = object;
} public void run() {
synchronized (object) {//上锁 for(int i=1;i<53;i++){
System.out.print(i+",");
if(i%2==0){
object.notifyAll();//唤醒其它争夺权限的线程
try {
object.wait();//释放锁,进入等待
System.out.println("数字打印类打全打印当前对象拥有对象锁的线程"+Thread.currentThread().getName());//输出当前拥有锁的线程名称
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
} } class zimu implements Runnable{
private Object object;
public zimu(Object object) { this.object = object;
}
public void run() {
synchronized (object) {
for(int j=65;j<91;j++){
char c = (char)j;
System.out.print(c);
object.notifyAll();//唤醒其它争夺权限的线程
try {
object.wait();//释放锁,进入等待
System.out.println("字母打印类打全打印当前对象拥有对象锁的线程"+Thread.currentThread().getName());//输出当前拥有锁的线程名称
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} }

实际运行的结果 :

1,2,A数字打印类打印当前对象拥有对象锁的线程shuzi
3,4,字母打印类打印当前对象拥有对象锁的线程zimu
B数字打印类打印当前对象拥有对象锁的线程shuzi
5,6,字母打印类打印当前对象拥有对象锁的线程zimu
C数字打印类打印当前对象拥有对象锁的线程shuzi
7,8,字母打印类打印当前对象拥有对象锁的线程zimu
D数字打印类打印当前对象拥有对象锁的线程shuzi
9,10,字母打印类打印当前对象拥有对象锁的线程zimu
E数字打印类打印当前对象拥有对象锁的线程shuzi
11,12,字母打印类打印当前对象拥有对象锁的线程zimu
F数字打印类打印当前对象拥有对象锁的线程shuzi
13,14,字母打印类打印当前对象拥有对象锁的线程zimu
G数字打印类打印当前对象拥有对象锁的线程shuzi
15,16,字母打印类打印当前对象拥有对象锁的线程zimu
H数字打印类打印当前对象拥有对象锁的线程shuzi
17,18,字母打印类打印当前对象拥有对象锁的线程zimu
I数字打印类打印当前对象拥有对象锁的线程shuzi
19,20,字母打印类打印当前对象拥有对象锁的线程zimu
J数字打印类打印当前对象拥有对象锁的线程shuzi
21,22,字母打印类打印当前对象拥有对象锁的线程zimu
K数字打印类打印当前对象拥有对象锁的线程shuzi
23,24,字母打印类打印当前对象拥有对象锁的线程zimu
L数字打印类打印当前对象拥有对象锁的线程shuzi
25,26,字母打印类打印当前对象拥有对象锁的线程zimu
M数字打印类打印当前对象拥有对象锁的线程shuzi
27,28,字母打印类打印当前对象拥有对象锁的线程zimu
N数字打印类打印当前对象拥有对象锁的线程shuzi
29,30,字母打印类打印当前对象拥有对象锁的线程zimu
O数字打印类打印当前对象拥有对象锁的线程shuzi
31,32,字母打印类打印当前对象拥有对象锁的线程zimu
P数字打印类打印当前对象拥有对象锁的线程shuzi
33,34,字母打印类打印当前对象拥有对象锁的线程zimu
Q数字打印类打印当前对象拥有对象锁的线程shuzi
35,36,字母打印类打印当前对象拥有对象锁的线程zimu
R数字打印类打印当前对象拥有对象锁的线程shuzi
37,38,字母打印类打印当前对象拥有对象锁的线程zimu
S数字打印类打印当前对象拥有对象锁的线程shuzi
39,40,字母打印类打印当前对象拥有对象锁的线程zimu
T数字打印类打印当前对象拥有对象锁的线程shuzi
41,42,字母打印类打印当前对象拥有对象锁的线程zimu
U数字打印类打印当前对象拥有对象锁的线程shuzi
43,44,字母打印类打印当前对象拥有对象锁的线程zimu
V数字打印类打印当前对象拥有对象锁的线程shuzi
45,46,字母打印类打印当前对象拥有对象锁的线程zimu
W数字打印类打印当前对象拥有对象锁的线程shuzi
47,48,字母打印类打印当前对象拥有对象锁的线程zimu
X数字打印类打印当前对象拥有对象锁的线程shuzi
49,50,字母打印类打印当前对象拥有对象锁的线程zimu
Y数字打印类打印当前对象拥有对象锁的线程shuzi
51,52,字母打印类打印当前对象拥有对象锁的线程zimu
Z数字打印类打印当前对象拥有对象锁的线程shuzi

结果分析:

通过结果可以看出:

在字母打一打印类里 调用完

object.notifyAll();//唤醒其它争夺权限的线程
object.wait();//释放锁,进入等待
后,拥有对象锁的线程是shuzi

在数字打印类里 调用完

object.notifyAll();//唤醒其它争夺权限的线程
object.wait();//释放锁,进入等待
后,拥有对象锁的线程是zimu

Java Object对象中的wait,notify,notifyAll的理解的更多相关文章

  1. Java之Object对象中的wait()和notifyAll()用法

    用一个例子来说明Object对象中的wait方法和notifyAll方法的使用. 首先定义一个消息类,用于封装数据,以供读写线程进行操作: /** * 消息 * * @author syj */ pu ...

  2. Java线程和多线程(二)——对象中的wait,notify以及notifyAll方法

    Java对象中的wait,notify以及notifyAll方法 在Java的Object类中包含了3个final的方法,这三个方法允许线程来交流资源是否被锁定.这三个方法就是wait(),notif ...

  3. Object中的wait,notify,notifyAll基本使用(转)

    让线程停止运行/睡眠的方法只有两个:Thread.sleep()或者obj.wait() 记住obj.nofity()并不能停止线程运行,因为notify虽然释放了锁,但依然会急促执行完synchro ...

  4. JVM系列之:详解java object对象在heap中的结构

    目录 简介 对象和其隐藏的秘密 Object对象头 数组对象头 整个对象的结构 简介 在之前的文章中,我们介绍了使用JOL这一神器来解析java类或者java实例在内存中占用的空间地址. 今天,我们会 ...

  5. Java Object 对象创建的方式 [ 转载 ]

    Java Object 对象创建的方式 [ 转载 ] @author http://blog.csdn.net/mhmyqn/article/details/7943411 显式创建 有4种显式地创建 ...

  6. Java Object 对象拷贝答疑

    Java Object 对象拷贝答疑 @author ixenos 摘要:在对象的clone过程需要注意的几点.关于关键字this.super 关于clone[对象拷贝] 在实际编程过程,有时候我们会 ...

  7. Java Object 对象拷贝

    Java Object 对象拷贝 @author ixenos JAVA 对象拷贝 Java里的clone分为:  1.浅拷贝:浅复制仅仅复制所考虑的对象,而不复制它所引用的对象,Object类里的c ...

  8. java中的wait(),notify(),notifyAll(),synchronized方法

    wait(),notify(),notifyAll()三个方法不是Thread的方法,而是Object的方法.意味着所有对象都有这三个方法,因为每个对象都有锁,所以自然也都有操作锁的方法了.这三个方法 ...

  9. 【java基础】java中Object对象中的Hashcode方法的作用

    以下是关于HashCode的官方文档定义: hashcode方法返回该对象的哈希码值.支持该方法是为哈希表提供一些优点,例如,java.util.Hashtable 提供的哈希表. hashCode  ...

随机推荐

  1. Qt编写安防视频监控系统5-视频回放

    一.前言 一般视频回放都会采用GB28181国标来处理,这样可以保证兼容国内各大厂家的NVR,毕竟在同一的国家标准下,大家都会统一支持国标的,就不需要根据各个厂家的SDK来做兼容处理,烦得很,厂家越来 ...

  2. 给mysql创建用户

    给mysql 创建用户过程: 1.进入mysql cmd下 2.输入密码:123 3.选择使用的数据库:use myeshop 4.创建新用户grant usage on *.* to 'cctvse ...

  3. 初学django框架 (urls,include子路由,render模板渲染)(一)

    一.urls url的使用为了告诉django哪个url调用那一段代码 如上左图所示,后面的test,test1如下图所示,为视图函数,通过前面的路径,调用后面函数的代码: 只有输入正确的url才会在 ...

  4. 关于使用Arduino做开发的理解

    转载自arduino中文社区 https://www.arduino.cn/thread-5414-1-1.html 见到很多人对Arduino的开发方法 .应用场景有误解,特别开个帖子说明下. 误解 ...

  5. eNSP使用-不同网段的互联

    就像下面这个场景: 1.基本配置 先点击左上角的——新建 然后咱们把要用的设备都拖到面板上去 成品就是这样的: 点击这个为他们添加备注 我们来配置一下实验编址 右键单击PC1设置(PC2同理,就不多演 ...

  6. [转帖]tr命令的用法

    tr命令的用法 https://www.cnblogs.com/bingguoguo/articles/9188703.html tr命令   tr命令可以对来自标准输入的字符进行替换.压缩和删除.它 ...

  7. 关于SpringMVC中的转发与重定向的说明

    写的非常详细,参看该地址:https://www.zifangsky.cn/661.html 总结: 1.请求转发:url地址不变,可带参数,如?username=forward 2.请求重定向:ur ...

  8. Java web server 基本实现原理

    public class WebServer { //服务端Socket只要一个,所以定义成static, 同一时间只能一个线程访问(主线程) private static ServerSocket ...

  9. 洛谷P2659 美丽的序列 单调栈模板

    P2659 美丽的序列 题目链接 https://www.luogu.org/problemnew/show/P2659 题目描述 为了研究这个序列的美丽程度,GD定义了一个序列的"美丽度& ...

  10. Ural 1248 Sequence Sum 题解

    目录 Ural 1248 Sequence Sum 题解 题意 题解 程序 Ural 1248 Sequence Sum 题解 题意 给定\(n\)个用科学计数法表示的实数\((10^{-100}\s ...