java多线程之wait/notify/notifyAll
程序员文章站
2022-05-04 20:53:06
...
前言:线程的状态
Java中线程中状态可分为五类:New(新建状态),Runnable(就绪状态),Running(运行状态),Blocked(阻塞状态),Dead(死亡状态),这几种状态的转换如下图
因为wait()等方法执行时需要获得锁,所以需要monitor对象,所以要在Synchronized作用域内执行,否则会报错
wait/notity/notityAll方法的使用:
wait()方法,将当前线程挂起,释放锁,让出cpu执行权,进入阻塞状态,方法里面加参数long timeout,如果timeout毫秒没有被唤醒,则自动唤醒。
package com.xhx.waitnotity;
import org.junit.Test;
/**
* xuhaixing
* 2018/7/29 9:21
**/
public class TestApp {
@Test
public synchronized void testWait(){
System.out.println(Thread.currentThread().getName()+"testWait-start-----");
try {
wait(2000);//等待2000毫秒,若不加参数,则一直等待,直到被notity唤醒
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"testWait-end-----");
}
@Test
public void testWaitMain() throws Exception {
TestApp testApp = new TestApp();
for (int i = 0;i<3;i++){
new Thread(()->testApp.testWait(),"thread"+i).start();
}
Thread.sleep(5000);
}
}
上面代码用三个线程去执行,在Synchronized中,wait释放锁,所以其它线程能获得锁,运行结果如下。
注释掉
// wait(2000);
运行结果是在同一个锁中顺序执行:
notity()方法为唤醒一个线程
notityAll()方法为唤醒所有
因为wait是通过对象的monitor对象来实现的,所以要用同一个对象去调用notity,就可以唤醒monitor上等待的线程了
@Test
public synchronized void testWait2() {
System.out.println(Thread.currentThread().getName() + "testWait-start-----");
try {
wait();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "testWait-end-----");
}
@Test
public void testNotityMain() throws Exception {
TestApp testApp = new TestApp();
for (int i = 0; i < 5; i++) {
new Thread(() -> testApp.testWait2(), "thread" + i).start();
}
Thread.sleep(1000);
synchronized (testApp) {
testApp.notify();
}
Thread.sleep(3000);
System.out.println("---------");
synchronized (testApp) {
testApp.notifyAll();
}
Thread.sleep(5000);
}
看下面执行结果:notify唤醒了一个线程,notifyAll唤醒了所有线程
注意:
调用wait方法会释放锁,被阻塞的线程必须要唤醒并且竞争到锁才能执行
下一篇: 设计模式(一)--策略模式