线程的等待与唤醒
程序员文章站
2022-05-04 17:57:54
...
线程的生命周期
在介绍线程的等待与唤醒之前, 我们先了解一下线程的生命周期。 其中包括6种状态, 分别为 New(新建)、Runnable(可运行)、Blocked(阻塞状态)、Waiting(无限等待)、TimeWaiting(计时等待)和Teminated(死亡状态)。
线程周期的各种状态:
线程的等待与唤醒
当处于运行状态下的线程调用 Thread 类中的 wait() 方法时,该线程便进入等待状态, 进入等待状态的线程必须调用 Thread 类中的 notify() 方法才能被唤醒, 而notifyAll()方法是将所有处于等待状态下的线程唤醒。
代码演示及现象
我们用一道代码题来进行说明:
题目需求:
请用“等待唤醒”机制编写一个程序,要求:
第一个线程:遍历1–1000所有的数字,在遍历过程中,如果发现这个数字 能同时被2,3,5,7整除,立即wait()退出等待,让第二个线程进入。
第二个线程:运行后,将一个计数器 + 1,之后再唤醒等待的线程。
主线程中:休息2秒,让两个线程全部执行完毕,打印“计数器”的结果。
public class Test31 {
//锁对象
final static Object obj = new Object();
//计数满足条件的数的个数
static int count = 0;
//用来判断锁的状态,默认为0状态
static int flag = 0;
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
//遍历1000
for (int i = 1; i <= 1000; i++) {
synchronized (obj) {
//1 状态,等待
if (flag == 1) {
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//0 状态
//判断
if (i % 2 == 0 && i % 3 == 0 && i % 5 == 0 && i % 7 == 0) {
//如果条件满足,打印i,并将flag调整为1,唤醒其他obj等待的线程
System.out.println(i);
flag = 1;
obj.notify();
}
}
}
//循环结束,通知线程2退出循环
synchronized (obj) {
flag = 2;
obj.notify();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
synchronized (obj) {
while (true) {
if (flag == 0) {
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else if (flag == 1) {
count++;
flag = 0;
obj.notify();
} else if (flag == 2) {
break;
}
}
}
}
}).start();
//主线程休眠2秒,保证子线程全部执行完
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//打印结果
System.out.println(count);
}
}
运行结果:
上一篇: 腾讯全民wifi免费公测 免费获取公测资格0元抢先体验
下一篇: 体悟生活的幽默妙段
推荐阅读
-
了解Java多线程的可见性与有序性
-
谈谈线程实例的现状、前景与机遇
-
php多线程pthreads的安装与使用,php多线程pthreads_PHP教程
-
php与shell实现多线程的简单例子
-
线程的等待与通知,如何使用Condition实现?
-
java 线程 Lock 锁使用Condition实现线程的等待(await)与通知(signal)
-
【多线程】Lock中的Condition实现等待通知
-
java 线程 Lock 锁使用Condition实现线程的等待(await)与通知(signal)
-
两个或多个线程执行完成之后继续执行之后的步骤,CountDownLatch与CyclicBarrier
-
linux线程间的同步与互斥知识点总结