为什么挥发物不能正常工作 [英] Why volatile is not working properly

查看:59
本文介绍了为什么挥发物不能正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天,我正在使用TimerTask创建一个超时作业,但是遇到了一个新问题,即我有一个static volatile boolean变量flag.我的理解是,此变量的值一经更改,便会由所有正在运行的thread通知.但是当我运行该程序时,我得到的输出低于可接受的水平.

Today I was creating one timeout job using TimerTask but fell in to a new problem where i have a static volatile boolean variable flag. My understanding is as soon as value of this variable get changed it is notified by all running thread. But when I ran this program I got below output which is not acceptable.

O/P:

--------------
--------------
DD
BB
Exiting process..
CC

我的期望是我的最后打印应该是退出过程.为什么会有这种奇怪的行为?

My expectation is my last print should be Exiting process.. Why is this strange behavior?

我的代码是:

public class TimeOutSort {

    static volatile boolean flag = false;

    public static void main(String[] args) {

        Timer timer = new Timer();
        timer.schedule(new TimerTask() {

            @Override
            public void run() {

                flag = true;
                System.out.println("Exiting process..");
                // System.exit(0);
            }
        }, 10 * 200);

        new Thread(new Runnable() {

            @Override
            public void run() {
                while (!flag)
                    System.out.println("BB");

            }
        }).start();

        new Thread(new Runnable() {

            @Override
            public void run() {
                while (!flag)
                    System.out.println("CC");

            }
        }).start();

        new Thread(new Runnable() {

            @Override
            public void run() {
                while (!flag)
                    System.out.println("DD");

            }
        }).start();
    }

}

编辑:我该如何实现?

推荐答案

volatile几乎意味着,每次线程访问变量时,必须确保使用对每个线程可见的版本(即,没有按线程缓存)

volatile pretty much means that each time a thread accesses a variable it must ensure to use the version visible to each thread (i.e. no per-thread caching).

flag设置为true后,此不会强制CC打印线程立即真正运行 .一个线程完全有可能(尤其是在单核计算机上)设置标志 并在CC打印线程有机会运行之前打印消息 .

This doesn't force the CC-printing thread to actually get to run immediately after the flag has been set to true. It's entirely possible (especially on a single-core machine) that one thread sets the flag and prints the message before the CC-printing thread even had a chance to run.

还:请注意,打印到System.out涉及获取锁(在println()调用中的某个位置),该锁可以修改测试代码的多线程行为.

Also: note that printing to System.out involves acquiring a lock (somewhere inside the println() call), which can modify the multi-threaded behaviour of test code.

这篇关于为什么挥发物不能正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆