线程的通信
@[toc]
涉及到的三个方法:
- wait():一但执行此方法,当前线程就进入阻塞状态,并释放同步监视器
- notify():一旦执行此方法,就会唤醒被wait的一个线程,如果有多个线程被wait,就唤醒优先级高的那个
- notifyAll():一旦执行此方法,就会唤醒所有被wait的线程
说明:
- wait()、notify()、notifyAll()三个方法必须使用在同步代码块或同步方法中
- wait()、notify()、notifyAll()三个方法的调用者必须是同步代码块或同步方法中的同步监视器,否则会出现java.lang.IllegalMonitorStateException异常
- wait()、notify()、notifyAll()这三个方法是定义在java.lang.Object类中
- (解释):要求同步监视器去调用,但是同步监视器又规定的任何对象都可以,所以相当于这个方法要任何对象都可以调用,所以就放在了Object当中
先由一个练习题例子来引入
题目:使用两个线程打印 1-100。线程1, 线程2 交替打印
package com.jsm.Java4;
public class lxt {
public static void main(String[] args) {
Number num = new Number();
Thread t1 = new Thread(num);
Thread t2 = new Thread(num);
t1.setName("线程1:");
t2.setName("线程2:");
t1.start();
t2.start();
}
}
class Number implements Runnable {
private int number = 1;
@Override
public void run() {
while (true) {
synchronized (this) {
notify();
if (number <= 100) {
System.out.println(Thread.currentThread().getName() + "打印:" + number);
number++;
try {
wait();//使得调用如下wait()方法的线程进入阻塞状态
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
break;
}
}
}
}
}
sleep()和wait()的异同
- sleep()方法在Java多线程01—线程的初步理解和基于Thread类创建线程关于Thread类中的方法中有提到
- wait()方法在本文中提到
- 相同点:一旦执行方法,都可以使得当前的线程进入阻塞状态
不同点:
- 声明的位置不同:Thread类中声明sleep(),Object类中声明wait()
- 调用的范围(要求)不同:sleep()可以在任何需要的场景下调用,wait()必须使用在同步代码块或者同步方法中调用
- 关于是否是否释放同步监视器的问题:如果两个方法都使用在同步代码块或者同步方法中,sleep()不会释放同步监视器,而wait会释放同步监视器