我正在编写一些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;
}
}
答案 0 :(得分:3)
如果仅需要线程间通信,而不需要mutual exclusion,请使用volatile
变量:
private static volatile boolean mRunning = false;
如果只有一个唯一的线程修改一个变量,而其他线程仅读取该变量,则您不需要额外的同步,volatile
就足够了(它保证读取该字段的任何线程都将看到最新的线程。书面价值)。
我应该这样做吗?
public void stop() {
synchronized (this) {
mRunning = false;
}
}
可以,但是不可以!无论如何,您都会得到意想不到的行为(此answer解释了原因)。
在问题描述的情况下,只需使用volatile
变量,该变量也不那么冗长,并且与synchronized
块相比,其性能可能更好。
答案 1 :(得分:2)
此代码会导致不良行为吗?
可以。
stop()
中的线程将能够将共享false
字段的值设置为boolean mRunning
。
但是,如果未将此字段声明为start()
,则volatile
中的线程可能看不到更改,因为执行start()
的线程不会使用当前对象的监视器,因此线程内存状态可能与主内存状态不同。
因此start()
可以继续在while
语句中循环。
因此,您必须确保将共享标志声明为volatile boolean mRunning
。