为什么我们必须使用“while"?用于检查竞争条件而不是“if" [英] Why we must use "while" for checking race condition not "if"

查看:70
本文介绍了为什么我们必须使用“while"?用于检查竞争条件而不是“if"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Thinking in java"中阅读了以下代码.

I read the following code in "Thinking in java".

synchronized(obj)
    {
        while (condition_not_matched)
        {
            obj.wait();
        }
        //continue
        dosomething();

    }

我的想法:
使用if"就可以了,因为wait"的意思是必须得到obj的锁监视器,这里只能执行一个线程.

What I think:
Use "if" is OK, because the "wait" means it must get the obj's lock monitor, and only one thread can executed here.

(1)为什么这里使用while (condition)"而不是if"?
(2)执行obj.wait()"时发生了什么?当前线程是否释放了obj"的锁?
(3)当另一个线程执行obj.notify()"时,前一个线程发生了什么(它是否重新获取了obj的锁?如果是,它必须condition_not_matched,所以if"就足够了.)
我错了吗?

(1)Why here use "while (condition)" not "if" ?
(2)What happend when executed "obj.wait()"? Does the currrent thread release the lock of "obj"?
(3)And when another thread executed "obj.notify()", what happend of the previous thread (Did it refetch the lock of obj or not ?if yes, it must condition_not_matched , so "if" is enough.)
Am I wrong?

推荐答案

使用 if 检查而不是在循环中重复检查是错误的.使用循环有多种原因.

Using an if check instead of checking repeatedly in a loop is a mistake. There are multiple reasons to use the loop.

一个是虚假唤醒",这意味着等待方法可以在没有通知线程的情况下返回:根据退出等待方法的线程推断它一定已经得到通知是无效的.这种情况可能不会经常发生,但必须加以处理.

One is the "spurious wakeup", which means the wait method can return without the thread having been notified: it's not valid to infer, based on the thread exiting the wait method, that it must have gotten notified. This may not happen a lot but it is a possibility that has to be handled.

但主要原因是:当您的线程等待时,它会释放锁.当它收到通知时,它没有锁,必须在退出等待方法之前再次获取它.仅仅因为线程得到通知并不意味着它是下一个获得锁的线程.如果线程根据线程没有锁的所有权时发生的事情来决定要做什么,在通知发生的时间和线程获得锁的时间之间,多个线程可能有机会对同一个共享对象进行操作,并且共享对象的状态可能不是您的线程认为的那样.使用 while 循环允许线程再次检查它正在等待的条件,并持有锁,在继续之前确认条件仍然有效.

But the main reason is this one: When your thread waits it releases the lock. When it receives a notification it doesn't have the lock and has to acquire it again before it can exit the wait method. Just because the thread got notified doesn't mean it's next in line to get the lock. If the thread decides what to do based on something that happened when the thread didn't have ownership of the lock, multiple threads may have had the opportunity to act on the same shared object between the time the notify happened and the time that the thread got the lock, and the state of the shared object may not be what your thread thinks it is. Using a while loop allows the thread to check the condition it's waiting on again, with the lock held, confirming that the condition is still valid before it proceeds.

这篇关于为什么我们必须使用“while"?用于检查竞争条件而不是“if"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆