我正在编写一些java代码,并有一个精心设计的示例,并且不太确定这是否是线程安全代码。
基本上,我有一个while循环来检查bool,并且我想从另一个线程中设置bool。
注意以下几点
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;
}
}发布于 2018-06-23 20:19:21
如果您只需要线程间通信,而不需要互斥,请使用volatile变量:
private static volatile boolean mRunning = false;如果只有一个唯一线程修改一个变量,而其他线程只读取该变量,那么您不需要额外的同步,volatile就足够了(它保证读取字段的任何线程都会看到最新的写入值)。
我应该这么做吗?
public void stop() {
synchronized (this) {
mRunning = false;
}
}你可以,但你不应该!无论如何,您会得到意想不到的行为(这个回答解释了原因)。
在问题中描述的情况下,只需使用一个volatile变量,这也较少冗长,而且与synchronized块相比,它的性能可能更好。
发布于 2018-06-23 20:14:02
这个代码会不会导致不良行为?
有可能。
stop()中的线程将能够将共享boolean mRunning字段的值设置为false。
但是,如果不将此字段声明为start(),则start()中的线程可能不会看到更改,因为执行start()的线程不接受当前对象上的监视器,因此线程内存状态可能与主内存状态不同。
所以start()可以在while语句中继续循环。
因此,您必须确保共享标志被声明为volatile boolean mRunning。
https://stackoverflow.com/questions/51004654
复制相似问题