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());
        }
    }
  • 相关阅读:
    SQL逻辑查询处理阶段
    将json字符串转换为json兑现
    JSTL核心标签库
    eclipse用4个空格代替Tab 每行80字符限制提示线显示空格
    MyEclipse8.6 性能优化
    jsp/servlet总结复习
    SQLServer之MERGE INTO
    as3效率提升
    让默认TextField更清晰地显示中文
    as3垃圾回收机制
  • 原文地址:https://www.cnblogs.com/zheaven/p/12153939.html
Copyright © 2011-2022 走看看