购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3.3 多线程的唤醒

线程的唤醒是与线程等待配套的方法,多用于多线程中出现线程的等待状态之后。多线程的唤醒分为随机唤醒一个线程及一次唤醒全部线程两种方法。

3.3.1 线程的notify()方法

作为经常与wait()方法配对出现的notify()方法,其能让进入WAITING状态的线程唤醒,但这一过程是随机的,即如果有多条线程处于WAITING状态,则一般会有其中的一条被唤醒,然后继续之前的工作。

通过之前的示例,我们已经大致了解到notify()方法的作用,但随机唤醒这一特性却没能非常好地表现出来。所以,下面的示例中,我们将能看到多线程情况下的随机唤醒。参考代码如下:

运行的参考结果如下:

可以看出,NewWaitingRunnabIe线程类包含一个监控锁monitorLock对象,其能使用该对象作为工具锁,对NewWaitingRunnabIe的实例进行wait()和notify()操作。

本示例中创建了三个线程实例,它们都使用了monitorLock01监控锁的wait()方法,即三个线程共用一个监控锁。另外,在唤醒阶段使用了三个monitorLock01.notify()方法,再次将三个处于WAITING状态的线程唤醒。

由输出结果的顺序也可以看出,被唤醒的线程有一定的随机性,不一定就按Thread-01、Thread-02、Thread-03的顺序唤醒。这是因为唤醒的过程需要通过一定的算法,如线程调度算法等运算后最终得出应该唤醒的线程。该示例中一共有三个线程会处在等待池中,所以当调用notify()方法唤醒时,会按一定的算法将其中的一个线程先唤醒,至于会先唤醒哪一个,也许真的无法给出一个绝对答案。

3.3.2 多线程的notifyAll()方法

理解好notify()方法之后,再来学习notifyAII()方法就容易许多,notifyAII()方法中包含AII一词,就是指调用该方法,会唤醒所有处在WAITING状态的线程。

在3.3.1小节的最后一个示例中,由于有三个线程使用了wait()方法,因此对应地使用了三个notify()方法进行唤醒操作。而如果使用notifyAII()方法,则使用一次即可。我们可以尝试注释之前的三个notify()方法,换成notifyAII()方法。参考代码如下:

运行结果与之前的示例相似,在此不再列出。

但有时调用notifyAII()方法并非像我们想象的那样,放任其一次唤醒处在等待池中的所有线程。因为在多线程的情况下,这样的全部唤醒操作往往要考虑到监控锁,特别是其他资源的竞争,若处理不好,可能会出现死锁问题。第7章将会介绍锁机制,关于死锁的详细问题将在后面讲解。 O8GAQu1r30UKsEuqDAlP2tXrg/GCEoVIeOr+zTD5Vo/FFbPXwMe01lgd9GOsGIKP

点击中间区域
呼出菜单
上一章
目录
下一章
×