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());
        }
    }
  • 相关阅读:
    普通线程类获取service,controller等spring容器类
    java拦截器获取请求完整参数
    分享几个免费IP地址查询API接口
    echarts热力地图
    echarts ajax请求demo
    mysql统计前24小时数据没有补0
    java获取来访者mac信息
    java获取本机mac物理地址
    mysql5.7以上基本配置
    springboot拦截异常信息发送邮件提醒
  • 原文地址:https://www.cnblogs.com/zheaven/p/12153939.html
Copyright © 2011-2022 走看看