首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从其他线程访问while循环bool,线程安全吗?

从其他线程访问while循环bool,线程安全吗?
EN

Stack Overflow用户
提问于 2018-06-23 20:07:31
回答 2查看 549关注 0票数 1

我正在编写一些java代码,并有一个精心设计的示例,并且不太确定这是否是线程安全代码。

基本上,我有一个while循环来检查bool,并且我想从另一个线程中设置bool。

注意以下几点

代码语言:javascript
复制
    public void start() {
    mRunning = true;

    thread = new Thread()
    {
        public void run()
        {
            while (mRunning) {

            }
        }
    }
    thread.start();
}

然后我在类上有一个变体,可以从另一个线程调用.

代码语言:javascript
复制
public void stop() {
    mRunning = false;
}

这个代码会不会导致不良行为?如果是的话,我应该就这么做吗?

代码语言:javascript
复制
public void stop() {
    sychronized(this) {
        mRunning = false;
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-06-23 20:19:21

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

代码语言:javascript
复制
private static volatile boolean mRunning = false;

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

我应该这么做吗?

代码语言:javascript
复制
public void stop() {
    synchronized (this) {
        mRunning = false;
    }
}

你可以,但你不应该!无论如何,您会得到意想不到的行为(这个回答解释了原因)。

在问题中描述的情况下,只需使用一个volatile变量,这也较少冗长,而且与synchronized块相比,它的性能可能更好。

票数 3
EN

Stack Overflow用户

发布于 2018-06-23 20:14:02

这个代码会不会导致不良行为?

有可能。

stop()中的线程将能够将共享boolean mRunning字段的值设置为false

但是,如果不将此字段声明为start(),则start()中的线程可能不会看到更改,因为执行start()的线程不接受当前对象上的监视器,因此线程内存状态可能与主内存状态不同。

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

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51004654

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档