您的位置:首页 > 大数据 > 人工智能

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重新开始、再继续
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息