Java中的奇怪行为,在多线程程序中具有不同步的访问权限

时间:2012-01-05 14:14:40

标签: java concurrency

我更改了一个值,用于确定while循环何时在单独的线程中终止。
我不想知道如何使这个工作。如果我只通过synchronized getters / setters访问变量测试,它会按预期工作..

我原以为,如果某些读/写命令由于并发而丢失,程序有时不会终止,但永远不会。这让我感到困惑..
我想知道为什么程序从不终止,没有print-command。我想了解为什么print-command会改变任何东西..

     

    public class CustomComboBoxDemo  {
        public static boolean test = true;
        public static void main(String[] args) {
            Thread user =new Thread(){
                @Override
                public void run(){
                    try {
                        sleep(2000);
                    } catch (InterruptedException e) {}
                    test=false;
                }
            };
            user.start();
            while(test) {
                System.out.println("foo"); //Without this line the program does not terminate..
            }
        }
    }

6 个答案:

答案 0 :(得分:8)

最可能的解释是变量只读一次,将while变为无限循环(或无操作)。由于您尚未将test声明为volatile,因此允许编译器执行此类优化。

从循环内部调用外部函数后,编译器无法再证明test在循环迭代中保持不变,并且不执行优化。

答案 1 :(得分:1)

如果test变量未定义为volatile,则编译器可能会将不包含任何操作的循环优化为主线程的while(true)循环,并且程序永远不会结束。

否则,实际检查test变量的值,当第二个线程更改其值时,主线程将离开while循环并且程序终止。

答案 2 :(得分:0)

我认为这与处理IO的方式有关。没有打印,你可能会看到使用所有可用CPU时间的java应用程序;对于打印,IO延迟可能会占用足够的CPU时间来进行其他处理。

测试这个理论的一种快速方法是将printlns放在线程的run()方法中,以查看线程是否实际执行。根据我的经验,无限的空循环会导致许多奇怪的行为。

那就是说,它似乎在我的工作站上在JDK 1.6.0_10_b23

下终止

答案 3 :(得分:0)

好像你的循环被错误地编译成忙碌的等待。在布尔值中添加volatile关键字可以纠正“问题”。

答案 4 :(得分:0)

public static boolean test = true;
public static void main(String[] args) {
    Thread user =new Thread(){
        @Override
        public void run(){
            try {
                sleep(2000);
            } catch (InterruptedException e) {}
            test=false;
            System.out.println("Thread.end <"+test+">");
        }
    };
    user.start();
    while(test);
}

这很有趣。编译器最有可能在进入无限循环时优化它,而不是在每个循环中读取值。

将测试定义为volatile可解决此问题并让您的程序终止

顺便说一句:你可能已经知道你应该使用user.join()来等待线程结束

答案 5 :(得分:0)

我不明白您尝试使用您知道未正确同步的代码。

有些人报告说,在他们的机器上,代码的行为与机器上的行为不同。严重同步代码的行为是未定义。尝试理解它的作用是没有意义的,因为该行为将随JVM版本或体系结构而改变。