zoukankan      html  css  js  c++  java
  • ThreadLocal使用详解

    The Thread-Specific Storage 线程保险箱

    官方解释

     This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID).

    该类提供线程局部变量。这些变量与普通的对应变量不同,因为每个访问一个变量的线程(通过其get或set方法)都有自己独立初始化的变量副本。ThreadLocal实例通常是希望将状态与线程(例如,用户ID或事务ID)关联的类中的私有静态字段。

    ThreadLocal的初始化设定值和set设置值

    package com.dwz.concurrency.chapter33;
    
    public class ThreadLocalSimpleTest {
        private static ThreadLocal<String> threadlocal = new ThreadLocal<String>() {
            @Override
            protected String initialValue() {
                return "dandan";
            };
        };
        
        public static void main(String[] args) throws InterruptedException {
            threadlocal.set("Alex");
            Thread.sleep(1000);
            System.out.println(threadlocal.get());
        }
    }

    模拟ThreadLocal的独立性

    package com.dwz.concurrency.chapter33;
    
    import java.util.Random;
    
    public class ThreadLocalComplexTest {
        private final static ThreadLocal<String> threadlocal = new ThreadLocal<>();
        
        private final static Random random = new Random(System.currentTimeMillis());
        public static void main(String[] args) throws InterruptedException {
            Thread t1 = new Thread(()->{
                threadlocal.set("T1");
                try {
                    Thread.sleep(random.nextInt(1000));
                    System.out.println(Thread.currentThread().getName() + "&&" + threadlocal.get());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            
            Thread t2 = new Thread(()->{
                threadlocal.set("T2");
                try {
                    Thread.sleep(random.nextInt(1000));
                    System.out.println(Thread.currentThread().getName() + "&&" + threadlocal.get());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            
            t1.start();
            t2.start();
            t1.join();
            t2.join();
            System.out.println("==========================");
            System.out.println(Thread.currentThread().getName() + "&&" + threadlocal.get());
        }
    }

    模拟线程保险箱

    package com.dwz.concurrency.chapter33;
    
    import java.util.HashMap;
    import java.util.Map;
    /**
     * The Thread-Specific Storage 模拟线程保险箱
     * 始终以当前线程作为key值
     * @param <T>
     */
    public class ThreadLocalSimulator<T> {
        private final Map<Thread, T> storage = new HashMap<>();
        
        public void set(T t) {
            synchronized (this) {
                Thread key = Thread.currentThread();
                storage.put(key, t);
            }
        }
        
        public T get() {
            synchronized (this) {
                Thread key = Thread.currentThread();
                T value = storage.get(key);
                if(null == value) {
                    return initialValue();
                }
                return value;
            }
        }
    
        public T initialValue() {
            return null;
        }
    }

    测试自定义线程保险箱

    package com.dwz.concurrency.chapter33;
    
    import java.util.Random;
    
    public class ThreadLocalSimulatorTest {
        private final static ThreadLocalSimulator<String> threadlocal = new ThreadLocalSimulator<String>() {
            @Override
            public String initialValue() {
                return "No value";
            };
        };
        
        //seed
        private final static Random random = new Random(System.currentTimeMillis());
        public static void main(String[] args) throws InterruptedException {
            Thread t1 = new Thread(()->{
                threadlocal.set("T1");
                try {
                    Thread.sleep(random.nextInt(1000));
                    System.out.println(Thread.currentThread().getName() + "&&" + threadlocal.get());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            
            Thread t2 = new Thread(()->{
                threadlocal.set("T2");
                try {
                    Thread.sleep(random.nextInt(1000));
                    System.out.println(Thread.currentThread().getName() + "&&" + threadlocal.get());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            
            t1.start();
            t2.start();
            t1.join();
            t2.join();
            System.out.println("==========================");
            System.out.println(Thread.currentThread().getName() + "&&" + threadlocal.get());
        }
    }
  • 相关阅读:
    私有属性的另类访问方式
    获取类所有属性和查看帮助文档
    类的私有属性及私方法(请注意属性的传值方式)
    类的私有属性及私方法
    类的定义
    怎么区分类变量和实例变量?
    面向对象编程案例04--访问控制
    面向对象编程案例03---继承之高级部分
    python 面向对象编程案例01
    静态方法
  • 原文地址:https://www.cnblogs.com/zheaven/p/12153939.html
Copyright © 2011-2022 走看看