Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用volatile变量停止线程_Java_Multithreading - Fatal编程技术网

Java 使用volatile变量停止线程

Java 使用volatile变量停止线程,java,multithreading,Java,Multithreading,基本上,如果我删除了不必要的东西,我有以下代码: public class Foo { private volatile boolean isFinished = false; private long timeOut = 60 * 1000; ... // Called asynchronously from another thread public setFinished(boolean value) { isFinished =

基本上,如果我删除了不必要的东西,我有以下代码:

public class Foo {
    private volatile boolean isFinished = false;
    private long timeOut = 60 * 1000;
    ...

    // Called asynchronously from another thread
    public setFinished(boolean value) {
        isFinished = value;
    }

    public wait() {
       ...
       long start = SystemClock.uptimeMillis();
       while(!isFinished && (SystemClock.uptimeMillis() - start) <= timeOut) {
           ...
       }

       if (isFinished) {
           // Log success!!!
           ...
       }
       else {
           // Log time out!!!
           ...
       }
    }
}
但有时,根据日志文件,会发生以下情况:

`wait()` is called waiting starts
`setFinished(true)` is called
`setFinished(true)` returns
about 60 seconds pass
"time out" entry in the log

有什么想法吗?

我唯一的猜测是,在这三个点中有某种东西阻碍了循环的执行:

while(!isFinished && (SystemClock.uptimeMillis() - start) <= timeOut) {
       ...
}

while(!isFinished&&(SystemClock.uptimeMillis()-start)如果
isFinished
仅从false转换为true,并且如果while循环已退出,则
isFinished
必须为true

即使您没有指定
volatile
(在实践中),情况也是如此,而且如果您指定了
volatile
(在理论上和实践中),情况肯定会如此

因此,我的猜测是第一个假设是错误的。如果我是你,我会试试这个:

// Called asynchronously from another thread
public setFinished(boolean value) {
    if(!value){
        throw new AssertionError("huh?");
    }
    isFinished = value;
}

然后看看会发生什么。

假设这应该是
if(isFinished)
,注意
value
setFinished()
@hmjd中未使用的参数,修复了这个问题。原始代码没有这个问题。那么
if
条件呢?它不应该是
if(isFinished)吗
?我认为您的命名令人困惑
isFinished
应该取消
iscancell
是的,可能就是这样。我有一些代码在while循环中使用
MessageQueue
/
Looper
。您能解释一下这对内存读取的影响吗?这在很大程度上取决于您如何使用队列。如果
MessageQueue
可以阻止exec注意,可能是这样。您可以尝试在该循环中打印时间标签,以确保进行了足够的超时检查。在while循环中,有几次执行完全停止。但仍然在while循环退出后,timeout
isFinished
应为
true
,并且不应在日志中打印超时。是的,它是如果它不是
真的
,我就说不出它怎么会变成
假的
,除非它被重新分配。
// Called asynchronously from another thread
public setFinished(boolean value) {
    if(!value){
        throw new AssertionError("huh?");
    }
    isFinished = value;
}