1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > java并发编程(十)使用wait/notify/notifyAll实现线程间通信

java并发编程(十)使用wait/notify/notifyAll实现线程间通信

时间:2021-07-30 22:35:50

相关推荐

java并发编程(十)使用wait/notify/notifyAll实现线程间通信

转载请注明出处:/ns_code/article/details/17225469

wait()方法:public final void wait() throws InterruptedException,IllegalMonitorStateException

wait()方法使得当前线程必须要等待,等到另外一个线程调用notify()或者notifyAll()方法。

当前的线程必须拥有当前对象的monitor,也即lock,就是锁。

线程调用wait()方法,释放它对锁的拥有权,然后等待另外的线程来通知它(通知的方式是notify()或者notifyAll()方法),这样它才能重新获得锁的拥有权和恢复执行。

要确保调用wait()方法的时候拥有锁,即,wait()方法的调用必须放在synchronized方法或synchronized块中。

一个小比较:

当线程调用了wait()方法时,它会释放掉对象的锁。

另一个会导致线程暂停的方法:Thread.sleep(),它会导致线程睡眠指定的毫秒数,但线程在睡眠的过程中是不会释放掉对象的锁的。

notify()方法public final native void notify() throws IllegalMonitorStateException

notify()方法会唤醒一个等待当前对象的锁的线程。

如果多个线程在等待,它们中的一个将会选择被唤醒。这种选择是随意的,和具体实现有关。(线程等待一个对象的锁是由于调用了wait方法中的一个)。

被唤醒的线程是不能被执行的,需要等到当前线程放弃这个对象的锁。

被唤醒的线程将和其他线程以通常的方式进行竞争,来获得对象的锁。也就是说,被唤醒的线程并没有什么优先权,也没有什么劣势,对象的下一个线程还是需要通过一般性的竞争。

notify()方法应该是被拥有对象的锁的线程所调用。

(This method should only be called by a thread that is the owner of this object's monitor.)

换句话说,和wait()方法一样,notify方法调用必须放在synchronized方法或synchronized块中。

wait()和notify()方法要求在调用时线程已经获得了对象的锁,因此对这两个方法的调用需要放在synchronized方法或synchronized块中。

一个线程变为一个对象的锁的拥有者是通过下列三种方法:

1.执行这个对象的synchronized实例方法。

2.执行这个对象的synchronized语句块。这个语句块锁的是这个对象。

3.对于Class类的对象,执行那个类的synchronized、static方法。

notifyAll()

public final native void notifyAll() throws IllegalMonitorStateException

该方法与notify()方法的工作方式相同,重要的一点差异是:

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

深入理解:

如果线程调用了对象的wait()方法,那么线程便会处于该对象的等待池中,等待池中的线程不会去竞争该对象的锁。

当有线程调用了对象的notifyAll()方法(唤醒所有wait线程)或notify()方法(只随机唤醒一个wait线程),被唤醒的的线程便会进入该对象的锁池中,锁池中的线程会去竞争该对象锁。

优先级高的线程竞争到对象锁的概率大,假若某线程没有竞争到该对象锁,它还会留在锁池中,唯有线程再次调用wait()方法,它才会重新回到等待池中。而竞争到对象锁的线程则继续往下执行,直到执行完了synchronized代码块,它会释放掉该对象锁,这时锁池中的线程会继续竞争该对象锁。

实例:/wenjieyatou/threadTest

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。