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 在ThreadLocal实例中获取volatile变量的目的_Java_Multithreading_Thread Local - Fatal编程技术网

Java 在ThreadLocal实例中获取volatile变量的目的

Java 在ThreadLocal实例中获取volatile变量的目的,java,multithreading,thread-local,Java,Multithreading,Thread Local,这是在一次技术会谈中向我提出的问题之一 public class MyClass { volatile int i; } 我使用上面的MyClass作为ThreadLocal,那么在这个类中获取任何可变变量有什么用呢 final ThreadLocal<MyClass> threadLocal = new ThreadLocal<MyClass>(); final ThreadLocal ThreadLocal=new ThreadLocal(); 如果该实

这是在一次技术会谈中向我提出的问题之一

public class MyClass {

    volatile int i;
}
我使用上面的MyClass作为ThreadLocal,那么在这个类中获取任何可变变量有什么用呢

final ThreadLocal<MyClass> threadLocal = new ThreadLocal<MyClass>();
final ThreadLocal ThreadLocal=new ThreadLocal();

如果该实例仅与
ThreadLocal
一起使用,并且没有被传递,那么
volatile
似乎没有什么意义


但是,请注意,
MyClass
只是一个与其他类类似的类:没有任何东西可以阻止它在不涉及线程本地存储的上下文中使用。在这些上下文中,变量是volatile是有意义的,Java中的volatile关键字保证volatile变量的值总是从主内存而不是从线程的本地缓存中读取

在某些情况下,Volatile变量可以作为在Java中实现同步的另一种方法,比如可见性。有了volatile变量,就保证了一旦写操作完成,所有读卡器线程都会看到volatile变量的更新值,没有volatile关键字,不同的读卡器线程可能会看到不同的值。让我们通过一个例子来理解这一点

public class C {
   private volatile int COUNTER=0;

    public static void main(String... q)
    {
        new C().call();
    }

    public void call()
    {
        new A().start();
        new B().start();
    }

    class A extends Thread
    {
        public void run()
        {
            int i =0;
            while(i<100)
            {
                COUNTER++;
                System.out.println(" A COUNTER : "+COUNTER+" *** "+"i : "+i);
                try{
                    Thread.sleep(50);
                }
                catch(Exception e)
                {

                }
                i++;
            }
        }
    }

    class B extends Thread
    {
        public void run()
        {
            int i =0;
            while(i<100)
            {
                COUNTER++;
                 System.out.println(" B COUNTER : "+COUNTER+" *** "+"i : "+i);
                   try{
                    Thread.sleep(50);
                }
                catch(Exception e)
                {

                }
                i++;
            } 
        }
    }
}
公共C类{
专用易失性int计数器=0;
公共静态void main(字符串…q)
{
新的C().call();
}
公开作废通知()
{
新的A().start();
新的B().start();
}
A类扩展线程
{
公开募捐
{
int i=0;
而(i

公共类线程本地

此类提供线程局部变量。这些变量不同 与它们的正常对应线程相比,每个访问一个线程的线程 (通过其get或set方法)有自己的独立初始化 变量的副本

Java编程语言允许线程访问共享的 变量(§17.1)。作为一项规则,确保共享变量 一致且可靠地更新,线程应确保 通过获得一个锁来独占使用这些变量, 传统上,强制这些共享变量互斥

Java编程语言提供了第二种机制,volatile 字段,这比出于某些目的锁定更方便

因此,在您的示例中,每个线程都有自己的MyClass实例。如果它是MyClass的唯一用途,则允许并发访问
i

volatile是“比锁定更方便”机制的关键词,用于“强制互斥”

因此,在这段代码中不需要volatile


此外,它还会降低性能。

您的意思是,如果我仅在threadlocal上下文中使用MyClass,则不使用volatile。但是,如果在该上下文之外使用它,则是的,变量为volatile可能很有意义。