zoukankan      html  css  js  c++  java
  • Java TheadLocal

    The ThreadLocal class in Java enables you to create variables that can only be read and written by the same thread. Thus, even if two threads are executing the same code, and the code has a reference to aThreadLocal variable, then the two threads cannot see each other's ThreadLocal variables.

    java里的ThreadLocal类可以让你创建一个只能被某个固定线程进行读写的变量,这样,即使两个线程执行相同的代码逻辑,并且代码逻辑里有一个ThreadLocal变量的引用,两个线程中的ThreadLocal变量仍然是相互独立的

    Creating a ThreadLocal

    Here is a code example that shows how to create a ThreadLocal variable:

    下面代码演示了如何创建一个ThreadLocal变量

    private ThreadLocal myThreadLocal = new ThreadLocal();
    

    As you can see, you instantiate a new ThreadLocal object. This only needs to be done once per thread. Even if different threads execute the same code which accesses a ThreadLocal, each thread will see only its own ThreadLocal instance. Even if two different threads set different values on the same ThreadLocalobject, they cannot see each other's values.

    上面代码实例化了一个ThreadLocal对象,实例化操作在每个线程中仅需要做一次即可。虽然多个线程执行相同的代码逻辑,并且代码逻辑里包含ThreadLocal引用,但是每个线程只能看到自己的ThreadLocal实例。所以即使两个线程对同一个ThreadLocal对象设置不同的值,他们也彼此看不到对方设置的值是什么。

    Accessing a ThreadLocal

    Once a ThreadLocal has been created you can set the value to be stored in it like this:

    myThreadLocal.set("A thread local value");
    

    You read the value stored in a ThreadLocal like this:

    String threadLocalValue = (String) myThreadLocal.get();
    

    The get() method returns an Object and the set() method takes an Object as parameter.

    Generic ThreadLocal

    You can create a generic ThreadLocal so that you do not have to typecast the value returned by get(). Here is a generic ThreadLocal example:

    private ThreadLocal<String> myThreadLocal = new ThreadLocal<String>();
    

    Now you can only store strings in the ThreadLocal instance. Additionally, you do not need to typecast the value obtained from the ThreadLocal:

    myThreadLocal.set("Hello ThreadLocal");
    
    String threadLocalValue = myThreadLocal.get();

    Initial ThreadLocal Value

    Since values set on a ThreadLocal object only are visible to the thread who set the value, no thread can set an initial value on a ThreadLocal using set() which is visible to all threads.

    由于ThreadLocal 对象中设置的值只对设置它的线程可见,这样就不能通过set() 方法在ThreadLocal上设置一个对所有线程可见的初始值。

    Instead you can specify an initial value for a ThreadLocal object by subclassing ThreadLocal and overriding the initialValue() method. Here is how that looks:

    但是可以通过重写ThreadLocalinitialValue()方法扩展ThreadLocal类实现给一个ThreadLocal对象指定初始值

    private ThreadLocal myThreadLocal = new ThreadLocal<String>() {
        @Override protected String initialValue() {
            return "This is the initial value";
        }
    };    
    

    Now all threads will see the same initial value when calling get() before having called set() .

    这样所有的线程都可以通过get()方法(中间没有单独调用set())得到相同的初始值

    Full ThreadLocal Example

    Here is a fully runnable Java ThreadLocal example:

    下面是一段可以完全运行的ThreadLocal实例

    public class ThreadLocalExample {
    
    
        public static class MyRunnable implements Runnable {
    
            private ThreadLocal<Integer> threadLocal =
                   new ThreadLocal<Integer>();
    
            @Override
            public void run() {
                threadLocal.set( (int) (Math.random() * 100D) );
        
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                }
        
                System.out.println(threadLocal.get());
            }
        }
    
    
        public static void main(String[] args) {
            MyRunnable sharedRunnableInstance = new MyRunnable();
    
            Thread thread1 = new Thread(sharedRunnableInstance);
            Thread thread2 = new Thread(sharedRunnableInstance);
    
            thread1.start();
            thread2.start();
    
            thread1.join(); //wait for thread 1 to terminate
            thread2.join(); //wait for thread 2 to terminate
        }
    
    }
    

    This example creates a single MyRunnable instance which is passed to two different threads. Both threads execute the run() method, and thus sets different values on the ThreadLocal instance. If the access to the set() call had been synchronized, and it had not been a ThreadLocal object, the second thread would have overridden the value set by the first thread.

    上面的例子创建了一个单独的MyRunnable实例,这个MyRunnable实例被作为参数传递到两个不同的线程中。两个线程在执行run方法时给ThreadLocal实例设置不同的值,如果调用set()方法的时候用synchronized关键字同步,而且不是一个ThreadLocal对象实例,那么第二个线程将会覆盖第一个线程所设置的值。

    However, since it is a ThreadLocal object then the two threads cannot see each other's values. Thus, they set and get different values.

    然而,由于是ThreadLocal对象,所以两个线程无法看到彼此的值。这样,他们可以设置或者获取不同的值。

    InheritableThreadLocal

    The InheritableThreadLocal class is a subclass of ThreadLocal. Instead of each thread having its own value inside a ThreadLocal, the InheritableThreadLocal grants access to values to a thread and all child threads created by that thread.

    InheritableThreadLocal类是ThreadLocal的子类。为了解决ThreadLocal实例内部每个线程都只能看到自己的私有值,所以InheritableThreadLocal允许一个线程创建的所有子线程访问其父线程的值。

  • 相关阅读:
    flutter 反序列化
    系统架构师-系统开发基础
    java Lambda表达式
    java异常
    HTTP缓存了解(一)
    设计模式(一):策略模式
    配置自己的ubuntu
    正则表达式:贪婪与非贪婪
    .htaccess文件
    mysql协议简析
  • 原文地址:https://www.cnblogs.com/codestarer/p/13635569.html
Copyright © 2011-2022 走看看