Discuss / Java / 廖大佬写的有一个点我看不明白,望大佬们指点。

廖大佬写的有一个点我看不明白,望大佬们指点。

Topic source

何小狗____

#1 Created at ... [Delete] [Delete and Lock User]

将while换成if后,程序运行的逻辑到底跟while有怎样的不同?

IM卓荣

#2 Created at ... [Delete] [Delete and Lock User]

while是循环语句, if是判断语句,逻辑当然是不一样。

if只在第一次获得锁之后判断一次,while在任意一次获得锁之后都会判断

其实老师那段关于if为什么不能用的原因没写明白,我在网上特意去查了查资料,发展我们对wait被唤醒时执行的位置有误解。

以下是查到的资料

结论:就是用if判断的话,唤醒后线程会从wait之后的代码开始运行,但是不会重新判断if条件,直接继续运行if代码块之后的代码,而如果使用while的话,也会从wait之后的代码运行,但是唤醒后会重新判断循环条件,如果不成立再执行while代码块之后的代码块,成立的话继续wait。

这也就是为什么用while而不用if的原因了,因为线程被唤醒后,执行开始的地方是wait之后。

廖雪峰

#5 Created at ... [Delete] [Delete and Lock User]

你这么想:

有A、B、C 3个线程在isEmpty()=true后进入了wait(),此时queue=[](空的)

D线程放入了一个task,此时queue=['task1'],然后唤醒所有等待线程。

此刻:A、B、C都要从wait()返回,但只有其中一个能先获得锁先执行,假设是A,它立刻调用remove()然后释放锁,这个时候,queue又空了

随后B、C如果获得锁不经过while判断直接remove(),它会报错。经过while判断发现queue还是空的,于是再次wait()

用while还是if,跟你的逻辑有关系。

_崔先生_

#6 Created at ... [Delete] [Delete and Lock User]

if 执行到一定位置之后不会往回跳

while会往回跳,再判断一遍,再执行再往回跳,再判断。。。。。。

相当于 秽土转生的鼬对大蛇兜发动的伊邪那美。。。。。。

_崔先生_

#7 Created at ... [Delete] [Delete and Lock User]

刚才那条是瞎写的

_崔先生_

#8 Created at ... [Delete] [Delete and Lock User]

就像是 你和很多人去饭店吃饭,人很多在排队。

你在外边等着,结果里边有一桌结账走人了,这时候服务生告诉所有人,说里边有位置啦。

有经验的服务生小while,放进一波人。于是他再检查,如果还有空位,还可以放进去一拨人。

结果小while肚子疼,上厕所去了。把任务交给了小if,他不会再去检查有木有空位,于是当饭桌有位置的时候,呼啦让所有人都进去了,可想而知,里边得打起来,只有一拨人能吃上饭,其他人得抓狂投诉吧,餐厅等着关门吧。

this.wait()相当于线程这部分代码卡在这一行了(也就是所有人等位),然后调用了notifyall()(餐厅说有位置啦),这时候经验老到的小while能继续判断(检查有几个空桌,放几波人),小if就会报错(让所有人进去)。

夢夢燈籠

#9 Created at ... [Delete] [Delete and Lock User]

看了上面的回复,个人理解。被notify唤醒的线程,是自this.wait()这一行后开始运行。

夢夢燈籠

#10 Created at ... [Delete] [Delete and Lock User]

倘若是if的话,已在代码块中,不再判断条件,向下顺序执行。

但while的话,在整个代码块的过程中都会持续判断条件。


  • 1
  • 2

Reply