Java将线程缓存刷新到实际副本时 [英] When Java refresh Thread Cache to actual copy

查看:102
本文介绍了Java将线程缓存刷新到实际副本时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读了几篇关于易失性线程缓存的文章,发现没有示例就太简短了,所以初学者很难理解.

请帮助我理解以下程序,

public class Test {
    int a = 0;
    public static void main(String[] args) {        
        final Test t = new Test();
        new Thread(new Runnable(){
            public void run() {
                try {
                    Thread.sleep(3000);
                } catch (Exception e) {}
                t.a = 10;
                System.out.println("now t.a == 10");
            }
        }).start();

        new Thread(new Runnable(){
            public void run() {
                while(t.a == 0) {}
                System.out.println("Loop done: " + t.a);
            }
        }).start();
    }

}

当我使a变量volatile并运行我的程序时,它会在一段时间后停止,但是当我将volatile移至a变量时,它会继续运行并且我的程序不会停止.

我对volatile的了解是当变量声明为volatile时,线程将直接读取/写入变量内存,而不是从本地线程缓存读取/写入. 如果未声明为volatile,那么可以看到更新实际值的延迟."

另外,根据我对刷新缓存副本的理解,我认为程序会在一段时间后停止,但是为什么在上面的程序中它会继续运行而不更新.

那么Thread何时引用其本地缓存开始引用主副本或使用主副本值刷新其值?

如果我理解上的错误,请纠正我....

请用一些小的代码段或链接向我解释.

解决方案

当变量声明为volatile时,线程将直接读取/写入变量内存,而不是从本地线程缓存读取/写入.如果未声明为volatile,则可以看到更新实际值的延迟.

首先,以上陈述为假.在机器代码级别上还有许多其他现象与线程局部变量缓存"无关.实际上,这个概念几乎不适用.

为了给您一些特定的重点,将允许JIT编译器转换您的代码

while(t.a == 0) {}

进入

if (t.a == 0) while (true) {}

每当t.a不是volatile时. Java内存模型允许将在数据争用中访问的任何变量视为访问线程是存在的唯一线程.显然,由于该线程没有修改t.a,因此可以将其值视为循环不变,并且不必重复进行检查... 永远.

I read few articles on volatile Thread cache and found either it is too much brief without examples, so it is very difficult for beginner to understand.

Please help me in understanding below program,

public class Test {
    int a = 0;
    public static void main(String[] args) {        
        final Test t = new Test();
        new Thread(new Runnable(){
            public void run() {
                try {
                    Thread.sleep(3000);
                } catch (Exception e) {}
                t.a = 10;
                System.out.println("now t.a == 10");
            }
        }).start();

        new Thread(new Runnable(){
            public void run() {
                while(t.a == 0) {}
                System.out.println("Loop done: " + t.a);
            }
        }).start();
    }

}

When I make a variable volatile and run my program then it stops after some time but when I remove volatile to a variable, then it goes on and my program is not stopping.

What I knew about volatile is "when variable is declared as volatile then thread will directly read/write to variable memory instead of read/write from local thread cache. if not declared volatile then one can see delay in updation of actual value."

Also, as per my understanding of refreshing the cached copy, I thought program will stop in some time but then why in above program it is continuing to run and not updating.

So when is Thread referring to its local cache starts referring to main copy or refresh its value with main copy value?

Please correct me if I am wrong in my understanding....

Please explain me with some small code snippet or link.

解决方案

when variable is declared as volatile then thread will directly read/write to variable memory instead of read/write from local thread cache. if not declared volatile then one can see delay in updation of actual value.

To begin with, the above statements are false. There are many more phenomena going on at the level of machine code which have nothing to do with any "thread-local variable caches". In fact, this concept is hardly applicable at all.

To give you something specific to focus on, the JIT compiler will be allowed to transform your code

while(t.a == 0) {}

into

if (t.a == 0) while (true) {}

whenever t.a is not volatile. The Java Memory Model allows any variable accessed in a data race to be treated as if the accessing thread was the only thread in existence. Since obviously this thread is not modifying t.a, its value can be considered a loop invariant and the check doesn't have to be repeated... ever.

这篇关于Java将线程缓存刷新到实际副本时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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