大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
今天看到一篇问题,提问线程唤醒顺序。
具体代码如下:
import java.util.LinkedList;
import java.util.List;
public class ThreadRunSort {
/**
* 对象锁
*/
private final Object object = new Object();
private List<Integer> sleep = new LinkedList<>();
private List<Integer> notify = new LinkedList<>();
/**
* 该线程作为一个唤醒线程
*/
public void startThread(int i) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
synchronized (object) {
try {
System.out.println(Thread.currentThread().getName()+"进入休眠");
sleep.add(i);
object.wait();
System.out.println(Thread.currentThread().getName()+"线程已经唤醒");
notify.add(i);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
t.setName("Thread"+i);
t.start();
}
public static void main(String[] args) {
ThreadRunSort a = new ThreadRunSort();
for(int i =1;i<22;i++){
a.startThread(i);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println();
for(int i =1;i<22;i++){
synchronized (a.object) {
a.object.notify();
}
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("休眠顺序"+a.sleep);
System.out.println("唤醒顺序"+a.notify);
}
}
发现,输入的顺序是不定的,比如:
休眠顺序[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
唤醒顺序[1, 5, 4, 3, 2, 7, 6, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 21]
但是,当修改了其中notify代码:
for(int i =1;i<22;i++){
try {
Thread.sleep(10); // 在这里sleep确保notify会顺序执行
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (a.object) {
a.object.notify();
}
}
顺序就变成
休眠顺序[1, 3, 4, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
唤醒顺序[1, 3, 4, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
可以理解在wait时候,放入的是一个FIFO的队列?每次notify其实就是出队的形式。(上面顺序有问题是因为线程按顺序出队后,抢占锁的顺序和CPU有关)
但是,把代码改成notifyAll后:
休眠顺序[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
唤醒顺序[21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
变成了stack出栈的形式。。
具体的问题还要再研究下。。。。
原问题传送门:https://ask.csdn.net/questions/387308#answer_972330
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/196104.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...