为了账号安全,请及时绑定邮箱和手机立即绑定

是从其他线程访问while循环布尔值,线程安全吗?

是从其他线程访问while循环布尔值,线程安全吗?

眼眸繁星 2021-04-06 16:17:54
我正在编写一些Java代码,并有一个人为的示例,并且我不确定这是否是线程安全代码。基本上,我有一个while循环来检查布尔值,我想从另一个线程将该布尔值设置为false。注意以下几点    public void start() {    mRunning = true;    thread = new Thread()    {        public void run()        {            while (mRunning) {            }        }    }    thread.start();}然后我在该类上有一个可变器,可以从另一个线程调用它。public void stop() {    mRunning = false;}这段代码会导致不良行为吗?如果是这样,我应该只是这样做吗?public void stop() {    sychronized(this) {        mRunning = false;    }}
查看完整描述

2 回答

?
慕虎7371278

TA贡献1802条经验 获得超4个赞

如果只需要线程间通信,而不需要互斥,请使用volatile变量:


private static volatile boolean mRunning = false;

如果只有一个唯一的线程修改变量,而其他线程仅读取该变量,则您不需要其他同步volatile就足够了(它保证任何读取该字段的线程都将看到最新写入的值)。


我应该这样做吗?


public void stop() {

    synchronized (this) {

        mRunning = false;

    }

}

可以,但是不可以!无论如何,您会得到意想不到的行为(此答案说明了原因)。


在问题描述的情况下,只需使用一个volatile变量,该变量也不那么冗长,并且与synchronized块相比,其性能可能更好。


查看完整回答
反对 回复 2021-04-21
?
蛊毒传说

TA贡献1895条经验 获得超3个赞

这段代码会导致不良行为吗?

它可能。
线程stop()将能够设置为false共享boolean mRunning字段的值 。
但是start()如果未声明此字段,则线程中的线程可能看不到更改,volatile因为正在执行的线程start()不会使用当前对象的监视器,因此线程内存状态可能与主内存状态不同。

因此 start()可以继续在while语句中循环。

因此,您必须确保将共享标志声明为volatile boolean mRunning


查看完整回答
反对 回复 2021-04-21
  • 2 回答
  • 0 关注
  • 171 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信