并发编程[5]_wait和notify
1. wait 和 notify
wait() 方法是Object类中的方法,他的作用是让当前线程进入等待状态,而使用notify() 方法可以唤醒。
- wait(long): void ,参数是毫秒,表示等待毫秒数,直到时间结束或被唤醒;
- wait(long, int): void ,第一个参数是毫秒,第二个参数是纳秒,如果纳秒在0-999999之间,则第一个参数值+1, 最后调用wait(long) 方法;
- wait(): void ,调用wait(0) ,表示无限等待。
- notify(): void,随机唤醒一个正在等待中的线程
- notifyAll():void ,唤醒所有正在等待中的线程
调用上述方法前,得保证当前线程是此对象的监视器所有者,即要获得对象的锁,否则直接调上述方法,会报出 java.lang.IllegalMonitorStateException 的错误。
简单的例子1:
public class Test1 {
private static final Logger log = LoggerFactory.getLogger(Test1.class);
// 自定义锁
private final static Object obj = new Object();
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread("thread1") {
@Override
public void run() {
try {
synchronized (obj){
log.debug("wait()");
obj.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
log.debug("唤醒后的操作");
}
};
thread.start();
Thread.sleep(1000);
synchronized (obj){
obj.notify();
log.debug("唤醒");
}
}
}
运行结果:
2021-04-25 22:31:49.151 [thread1] - wait()
2021-04-25 22:31:50.152 [main] - 唤醒
2021-04-25 22:31:50.152 [thread1] - 唤醒后的操作
2. wait 和 sleep
wait 和 sleep 都是可以让线程进入休眠的状态,但是具体的又有很大的不同。
sleep | wait | |
---|---|---|
所属类 | Thread 类中的静态方法 | Object 类中的非静态方法 |
参数 | 有参 | 有参和无参 |
调用后的线程状态 | TIMED_WAITING | WAITING(无参时) 或 TIMED_WAITING |
锁 | 不会释放锁 | 会释放锁 |
使用场景 | 任何地方都能使用 | 需取得锁后,才能调用 |
例子:
根据运行结果的时间来判断会不会释放锁。
测试sleep不会释放锁:
public class Test1 {
private static final Logger log = LoggerFactory.getLogger(Test1.class);
// 自定义锁
private final static Object obj = new Object();
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread("thread1") {
@Override
public void run() {
try {
synchronized (obj){
log.debug("sleep(5000) 中...");
Thread.sleep(5000);
}
log.debug("休眠结束...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread1.start();
Thread.sleep(1000);
log.debug("线程1:{}",thread1.getState());
synchronized (obj){
log.debug("正在访问obj...");
}
}
}
运行结果:
2021-04-25 22:55:50.762 [thread1] - sleep(5000) 中...
2021-04-25 22:55:51.762 [main] - 线程1:TIMED_WAITING
2021-04-25 22:55:55.764 [thread1] - 休眠结束...
2021-04-25 22:55:55.764 [main] - 正在访问obj...
测试wait会释放锁:
public class Test1 {
private static final Logger log = LoggerFactory.getLogger(Test1.class);
// 自定义锁
private final static Object obj = new Object();
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread("thread1") {
@Override
public void run() {
try {
synchronized (obj){
log.debug("wait(5000) 中...");
obj.wait(5000);
}
log.debug("休眠结束...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread1.start();
Thread.sleep(1000);
log.debug("线程1:{}",thread1.getState());
synchronized (obj){
log.debug("正在访问obj...");
}
}
}
运行结果
2021-04-25 22:55:07.307 [thread1] - wait(5000) 中...
2021-04-25 22:55:08.308 [main] - 线程1:TIMED_WAITING
2021-04-25 22:55:08.308 [main] - 正在访问obj...
2021-04-25 22:55:12.308 [thread1] - 休眠结束...