java 线程之对象的wait()与notify方法

sancaiodm Java 2022-02-27 1121 0

先了解一下wait与 notify的正解使用示范

image.png

如果将示例中下面的lock改为lock2则会造成运行异常:

image.png

[1]对象的wait与notify方法

这两个方法都object类的方法,并非线程Thread类的方法,

Object.wait()|Obejct.wait(Long timeout) 线程等待,

Obejct.wait(Long timeout) 带时间参数的,单位为毫秒,表示最多等待这么长的时间,如果参数为0则代表无限期的等待,

Obejct.wait() 不带时间参数,则表示无限期的等待下去,实际调用的是Obejct.wait(0) ;

当调用此wait方法时,则会把当前线程放到条件队列上并堵塞,就会停止执行当前业务逻辑,转为等待状态,直到为唤醒,

Obejct.wait() 调用wait方法后,线程为释放对象锁。


Object.notify() 线程唤醒,将等待状态下的线程唤起,继续执行任务(从条件队列中随机选一个线程,将其从队列中移除并唤醒)

Object.notify()与Object.notifyAll()后者为移除条件队列中所有的线程并全部唤醒它们。

wait()方法与notify()方法必须在持有对象锁时才可以被调用(在Synchronized修饰的方法或是代码块中调用)。


[2]工作原理 

i当对象调用了wait方法后,则线程就会进入到对象的等待队列,这里请大家要知道,每对象默认有一把对象锁和一个等待队列,


wait与notify方法都必须先获取目标对象的监视器(必须包含在synchronized中),才能够调用。

这样设计的好处就是:防止多个线程并发运行时,程序的执行不会混乱


------------------------------------------------------------------------------------------------------------

wait()方法与Sleep()的区别

【1】使用语法不同

wait方法必须在Synchronized修饰的方法或是代码块中调用,不然会运行时抛出异常(在编译时不会显示出任何异常),而sleep()方法可以单独使用,无需配置Synchronized一起使用。

【2】所属的类不同,wait方法是object类的方法,而sleep方法是Thread类的方法。

【3】线程进入状态不同

调用sleep方法则线程会进入TIMED_WAITING有时限的等待状态,而调用wait无参的方法,则线程为进入无时限的WAITING状态。

【4】唤醒方式不同

使用sleep方法必须传入一个超时的时间参数,且过了此超时的时间之后,线程会自动唤醒,但wait()方法的会进入一个无时限的休眠状态,直到另一个线程调用nofity或是notifyAll()方法后才行被唤醒,前者是主动唤醒,后者是被动唤醒

【5】对持有对象锁不同

sleep方法会一直持有对象锁,而wait方法会在被调用后主动释放锁,

wait方法会在被调用后主动释放锁,这就也是其它线程持有共享对象锁并在Synchronized方法内调用notify方法唤醒它,如果wait方法在被调用后不主动释放对象锁,则其它对象是无法拿到对象锁进入Synchronized方法内执行notify()方法

评论