wait, notify 和 notifyAll区别

作用

java使用wait(),notify(),notifyAll()来进行线程之间的通讯

共同点:

都是Java Object对象里面的方法:
wait()方法:如果对象调用了wait方法就会使持有该对象的线程把该对象的控制权交出去,然后处于等待状态。
notify()方法:如果对象调用了notify方法就会通知某个正在等待这个对象的控制权的线程可以继续运行。
notifyAll()方法:如果对象调用了notifyAll方法就会通知所有等待这个对象控制权的线程继续运行。

wait方法:

1.该方法用来将当前线程置入休眠状态,同时释放掉当前对象的锁,在调用wait之前,线程必须要获得该对象的对象锁。
2.由于需要获得对象锁才能使用wait()方法,说明调用wait()方法必须在sychronized{}代码块或者synchroniezd方法中。调用wait()释放了当前对象的锁。其他线程就有可能进入到synchronized方法。
3.如果调用wait()时,没有持有适当的锁,则抛出IllegalMonitorStateException,它是RuntimeException的一个子类,因此,不需要try-catch结构。
4.wait()醒来之后执行wait()后面一句代码,依次从后面执行

notify方法

1.方法调用之前由于也需要获取该对象的锁,所以使用的位置: synchronized方法中或者synchronized代码块中。
2.通知那些可能等待该对象的对象锁的其他线程。如果有多个线程等待,则线程规划器任意挑选出其中一个wait()状态的线程来发出通知,并使它等待获取该对象的对象锁(notify后,当前线程不会马上释放该对象锁,wait所在的线程并不能马上获取该对象锁,要等到程序退出synchronized代码块后,当前线程才会释放锁,wait所在的线程也才可以获取该对象锁
3.wait()方法执行完毕之后,会立刻释放掉锁,如果没有再次使用notify,其他wait()的线程由于没有得到通知,会继续阻塞在wait()的状态,等待其他对象调用notify或者notifyAll来唤醒。

notifyAll方法

1.使用位置和notify一样
2.notifyAll唤醒所有处于wait的线程(即全部被唤醒,不再等待notify或notifyAll,但由于此时还没有获取到该对象锁,因此还不能继续往下执行),变成等待获取该对象上的锁,一旦该对象锁被释放(notifyAll线程退出调用了notifyAll的synchronized代码块的时候),他们就会去竞争。如果其中一个线程获得了该对象锁,它就会继续往下执行,在它退出synchronized代码块,释放锁后,其他的已经被唤醒的线程将会继续竞争获取该锁,一直进行下去,直到所有被唤醒的线程都执行完毕。)

wait(long)和wait(long,int)

设置等待超时时间的,对于wait(long),如果在等待线程超过了设置的时间,则需要通过竞争重新获取锁。另外,需要知道,如果设置了超时时间,当wait()返回时,我们不能确定它是因为接到了通知还是因为超时而返回的,因为wait()方法不会返回任何相关的信息。但一般可以通过设置标志位来判断,在notify之前改变标志位的值,在wait()方法后读取该标志位的值来判断,当然为了保证notify不被遗漏,我们还需要另外一个标志位来循环判断是否调用wait()方法。

总结:

1.如果线程调用了wait方法,那么线程进入线程池处于等待状态
2.notifyAll唤醒所有的线程,notify随机唤醒一个。notify唤醒的是任意一个线程。当前notify的线程,是随机被执行的。notify()调用的地方也是synchronized代码块或者synchronized方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值