龙空技术网

“全栈2019”Java多线程第十八章:同步代码块双重判断详解

人人都是程序员 318

前言:

现在各位老铁们对“c语言双重判断”大概比较关怀,看官们都需要剖析一些“c语言双重判断”的相关内容。那么小编同时在网络上汇集了一些对于“c语言双重判断””的相关知识,希望看官们能喜欢,各位老铁们快快来学习一下吧!

难度

初级

学习时间

30分钟

适合人群

零基础

开发语言

Java

开发环境JDK v11IntelliJ IDEA v2018.3友情提示本教学属于系列教学,内容具有连贯性,本章使用到的内容之前教学中都有详细讲解。本章内容针对零基础或基础较差的同学比较友好,可能对于有基础的同学来说很简单,希望大家可以根据自己的实际情况选择继续看完或等待看下一篇文章。谢谢大家的谅解!1.温故知新

在《“全栈2019”Java多线程第十六章:同步synchronized关键字详解》一章中介绍了synchronized关键字。

在《“全栈2019”Java多线程第十七章:同步锁详解》一章中介绍了同步代码块/方法中的同步锁。

现在我们来讲解同步代码块中的双重判断。

2.别让同步使多线程变单线程

很多时候,不恰当使用同步会使得多线程变单线程。

例如,我们把上一小节中的卖票程序再演示一遍。

演示:

请使用程序描述卖票。

请观察程序代码及结果。

代码:

TicketingTaskThread类:

Main类:

结果:

从运行结果来看,程序没有什么问题。

该程序代码在之前的章节中分析过很多次,这里就不再赘述了,不清楚的小伙伴请查阅之前的文章。

现在我想说的就是该程序看似是一个多线程程序,因为我们启用了两个线程:

问题是,你启用两个线程就一定是两个线程都在做事吗?

为了弄清楚该程序是几个线程在做事,我们把线程名称输出一下,这里修改TicketingTaskThread类:

Main类无需修改。

运行程序,执行结果:

从运行结果来看,整个程序运行下来只有一个叫“Thread-0”的线程在跑,而这个叫“Thread-0”的线程就是它:

明明有两个线程在执行这个卖票任务,为什么从头卖到尾都只有一个线程呢?

因为同步。

说具体点就是什么内容该同步,什么内容不该同步,同步的范围从哪到哪这些都很重要。

该例子中,我们同步的范围是:

也就是说当有一个线程进入该同步代码块后,它就一直在执行这个while循环,直至循环完毕。

问题也就找到了:while循环完毕也就意味着票也卖完了,因为是同步,所以当一个线程进来执行以后,其他线程无法再进入该同步代码块,从头到尾都是一个线程执行的。

以上就是同步让多线程变单线程的原因。

有没有解决办法呢?

有,我们将while循环体内容同步就好了,这样每个线程都有机会卖到票。

事实是不是我们想的这样呢?来修改TicketingTaskThread类试试:

Main类无需修改。

运行程序,执行结果:

从运行结果来看,程序并不完美。有错误车票出现:

前面1-100号票都让一个叫“Thread-0”的线程卖了,好不容易轮到“Thread-1”线程卖票,却卖出了一张错票。

为什么会出现错票呢?

还是来一张图解释解释吧:

动图中的1号窗口就是“Thread-0”,2号窗口就是“Thread-1”。

在程序代码中表现就是“Thread-0”和“Thread-1”两个线程同时满足了while循环的条件:

都进入了循环体,接下来就是谁先执行同步代码块和谁后执行同步代码块里面的内容问题了。

问题就出在我们在同步代码块里面没有进行条件判断:

导致第一个线程进来执行完以后,此时车票已经卖完了,后面的第二个线程再进入同步代码块开始执行的时候,没有再次判断车票是否大于0,于是就是出现了错票。

解决办法:在同步代码块内部再次判断条件是否成立。

接着,我们就按照解决办法来修改TicketingTaskThread类:

Main类无需修改。

运行程序,执行结果:

从运行结果来看,程序经过修改之后变得健壮许多。没有出现错票。

以上就是同步代码块的双重判断全部内容。

简单回顾一下程序代码,在同步代码块的外面和里面各判断一次,这被称之为双重判断。

例如,我们程序代码中,第一次判断条件是在同步代码块的外面:

第二次判断条件是在同步代码块的里面:

希望大家可以更准确的找到哪些代码是需要同步的,哪些代码是不需要同步的,然后再想想需不需要双重判断。

总结在同步代码块的外面和里面各判断一次,这被称之为双重判断。使用同步时,找准哪些代码是需要同步的,哪些代码是不需要同步的,然后再想想需不需要双重判断。

至此,Java中同步代码块双重判断相关内容讲解先告一段落,更多内容请持续关注。

答疑

如果大家有问题或想了解更多前沿技术,请在下方留言或评论,我会为大家解答。

上一章

“全栈2019”Java多线程第十七章:同步锁详解

下一章

“全栈2019”Java多线程第十九章:死锁详解

学习小组

加入同步学习小组,共同交流与进步。

方式一:关注头条号Gorhaf,私信“Java学习小组”。方式二:关注公众号Gorhaf,回复“Java学习小组”。全栈工程师学习计划

关注我们,加入“全栈工程师学习计划”。

版权声明

原创不易,未经允许不得转载!

标签: #c语言双重判断