02-03线程的等待(挂起)与唤醒(继续)
2018-01-27 22:59
429 查看
002基础api-03线程的等待(挂起)与唤醒(继续)
本节要点:- suspended与resume方法
- wait与notify()(notifyAll):属于Object方法;必须放在synchronized语句块中,且监视的对象与使用的对象要保持一致;notify是随机唤醒一个wait区的线程。
suspended与resume方法
suspended方法是暂停线程,resume则是让线程继续。这两个方法已经是过期的方法,这里就不多加讨论。知道一下就行。wait()与notify()(notifyAll)
这三个方法并不是Thread类的,而是Object类的方法,也就是说所有的对象都可以调用。建议不要使用线程对象去调用这些方法。下面看一下这些方法的申明,其中wait有三个重载的方法。public final void wait() throws InterruptedException; public final void wait(long timeout, int nanos) throws InterruptedException; public final native void wait(long timeout) throws InterruptedException; public final native void notify(); public final native void notifyAll();
大家需要注意的是上述方法都必须在对应 的synchronized语句中才能调用,负责会抛出IllegalMonitorStateException异常。所谓对应即谁调用监视谁。我们来验证一下。运行下面的代码你会得到一个IllegalMonitorStateException。释放在主线程中synchronized的注释语句,也会得到同样的异常。只有把synchronized监视的对象改为object1时才会运行正常,当然唤醒的线程又会再次进入wait等待区。
public static void main(String[] args) { Object object = new Object(); Object object2 = new Object(); Thread thread = new Thread() { @Override public void run() { while (true) { synchronized (object) { System.out.println("===线程开始==="); try { object.wait(); System.out.println("--接着上次执行---"); } catch (InterruptedException e) { e.printStackTrace(); } } } } }; thread.start(); System.out.println("main thread end"); // synchronized (object2) { object.notifyAll(); System.out.println("唤醒线程"); // } }
wait方法是让当前执行的线程等待在调用该方法的对象的wait区域的方法。同时wait方法的重载还可以指定等待的时间(查看源码你会发现所有的wait方法最终都会去调用wait(long timeout))。wait方法是可以抛出InterruptedException异常的,在中断时是可以被捕获的。
notify和notifyAll()方法前者时随机唤醒调用该方法的对象的wait区的一个线程,后者时唤醒所有wait区的线程。
下面我们来看一下综合的案例。
public static void main(String[] args) throws InterruptedException { Object object = new Object(); for (int i = 0; i < 30; i++) { Thread thread = new Thread() { @Override public void run() { synchronized (object) { System.out.println(Thread.currentThread().getName()); try { object.wait(); System.out.println( Thread.currentThread().getName() + "--接着上次执行---"); } catch (InterruptedException e) { e.printStackTrace(); } } } }; thread.setName("线程i " + i); thread.start(); Thread.sleep(10);// 保证各个线程都按顺序等待在object的wait区。 } System.out.println("main thread end"); Thread.sleep(100); for (int i = 0; i < 20; i++) { synchronized (object) { object.notify(); System.out.println("notify唤醒线程"); } } // synchronized (object) { // object.notifyAll(); // System.out.println("notifyAll唤醒线程"); // } }
首先我们用notify唤醒线程。多运行几次,你就很容易发现它每次都只唤醒一个wait的线程,而且还是随机的。notifyAll唤醒线程则时全部唤醒。
动手:
尝试一下用wait指定等待时间来唤醒线程。单词
illegal \ (ˌ)i(l)-ˈlē-gəl \ adjective非法的、不合法的; noun 非法移民monitor \ ˈmä-nə-tər \ verb 监视、监督 noun 班长、监视器、监听员
state \ ˈstāt \ noun国家、状态、州
notify \ ˈnō-tə-ˌfī \ verb通知、报告
suspend \ sə-ˈspend\ verb 暂停、中止、悬浮
resume \ ri-ˈzüm\ noun 简历、履历 verb重新开始、再继续
相关文章推荐
- 被唤醒后的线程到底重新执行同步代码块还是从那是等待的那里继续执行
- java 线程wait()与notify()的用法(被唤醒后的线程到底重新执行同步代码块还是从那是等待的那里继续执行)
- java 线程wait()与notify()的用法(被唤醒后的线程到底重新执行同步代码块还是从那是等待的那里继续执行)
- 根据Linux 线程挂起与唤醒原理,实现Sleep的暂停与继续
- Java-线程Thread等待与唤醒
- java 多线程—— 线程等待与唤醒
- Java线程之等待wait唤醒notify示例(一)
- VC线程的挂起及唤醒
- java线程技术6_线程的挂起和唤醒
- java 多线程系列基础篇(五)之线程等待与唤醒
- Java并发编程-02-线程的中断,休眠和等待线程的终止
- java 线程等待与唤醒
- JavaSE 多线程 线程间通讯—等待唤醒机制代码优化(背下来)
- Java-线程Thread等待与唤醒
- java线程技术6_线程的挂起和唤醒[转]
- java基础12:线程间通信----等待唤醒机制
- Monitor线程操作(当一个线程中处于等待状态时,另外一个线程来解锁它的等待状态继续执行下去)
- 线程等待一定时间和及时返回继续执行,以及等待线程退出。
- Thread(线程间通讯,等待唤醒机制)
- Java并发:等待事件发生后所有线程继续执行