当前位置 : 主页 > 编程语言 > java >

Java-GuardedBlocks与BusyWaitting忙等待

来源:互联网 收集:自由互联 发布时间:2022-07-13
Guarded[ˈɡɑːrdɪd] 守卫 现在有这样一个需求,两个线程T1,T2,线程T1会一直等待T2通知,当T2通知T1打印"MYS"的时候,T1就会打印MYS 下面是T1的代码,它无限轮询 boolean a = true; while(a) { //


Guarded[ˈɡɑːrdɪd] 守卫
现在有这样一个需求,两个线程T1,T2,线程T1会一直等待T2通知,当T2通知T1打印"MYS"的时候,T1就会打印MYS

下面是T1的代码,它无限轮询

boolean a = true;
while(a) {
// 什么都不做
}
System.out.println("MYS");

下面是T2的代码

a = false;

当T2对a进行赋值之后,T1就会打印出MYS,上述这种达到两个(甚至多个)线程之间通信的方式,就叫GuardedBlocks,也叫忙等待(BusyWaitting)

现在知道了什么是GuardedBlocks,那么来说一说这种做法的缺点,就是占用CPU使用率很高,因为一直轮询,但是又没做任何事情,这明显是对CPU的浪费,所以对GuardedBlocks使用了一种改进方式,这种改进方式是两个进程之间使用两个条件来通讯,而不是上述代码中仅仅通过a的值这一个条件来判断,改进之后如下
1.T1等待T2通知a修改完毕
2.T接到通知之后,判断a是否真的修改完毕

下面是T1改进后的代码,它虽然依旧无限循环,但是这只是语义上的体现,实际上并不是真的循环多次

boolean a = true;
while(a) {
// 添加一个类似wait的方法,然后此处将T1阻塞或者挂起
T1.wait();
}
System.out.println("MYS");

下面是T2改进后的代码

//首先将a=false
a = false;
//然后通知T1,a的值已经修改,伪代码类似下面这样
notify(T1);

经过改进后的代码,可以很大程度上减少CPU的无用消耗

注意:
java中,wait底层实现是挂起,挂起是CPU的概念,即使不存在操作系统,CPU执行多任务的时候,没有被执行的任务,此时的状态就叫做挂起

阻塞是线程上的概念,而线程是建立在操作系统之上的,阻塞可以用挂起来实现,也可以用其他方式来实现,挂起更贴近底层,而阻塞更靠上


上一篇:Java-ReentrantLock-NonfairSync/FairSync
下一篇:没有了
网友评论