zoukankan      html  css  js  c++  java
  • ThreadLocal应用示例

    ThreadLocal从字面意思来看是线程本地(变量),有什么作用呢?

    存放在ThreadLocal中的变量值只在当前线程中可见及使用。那仅在当前线程可用,自然就不存在多线程并发冲突问题,是一种空间(每个线程单独存储变量)换时间的解决多线程并发问题的方式。

    下面举例说明:

    package threadLocalDemo;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class Demo {
    
        static ThreadLocal<String> threadLocal = new ThreadLocal<>();
    
        public static void main(String[] args) throws InterruptedException {
            //创建一个仅有一个线程的线程池(模拟在一个线程中的前后操作)
            ExecutorService executorService = Executors.newFixedThreadPool(1);
            //线程提交任务:线程中设置ThreadLocal变量并打印
            executorService.submit(() -> {
                threadLocal.set("hello");
                System.out.println(Thread.currentThread().getName()+":"+threadLocal.get());
            });
            //线程延迟1s提交任务:获取ThreadLocal变量并打印
            Thread.sleep(1000);
            executorService.submit(() -> {
                System.out.println(Thread.currentThread().getName()+":"+threadLocal.get());
            });
            //线程延迟1s提交任务:获取ThreadLocal变量并打印
            Thread.sleep(1000);
            executorService.submit(() -> {
                System.out.println(Thread.currentThread().getName()+":"+threadLocal.get());
            });
            executorService.shutdown();
        }
    }

    打印结果如下:

    pool-1-thread-1:hello
    pool-1-thread-1:hello
    pool-1-thread-1:hello

    说明只要在当前线程中设置ThreadLocal变量后,线程的后续操作时都可以拿到此变量。

    另外:在某些场景下,我们在同一线程的前后操作中是需要修改或者清空ThreadLocal变量的,当然也有相关的API,举例如下:

    package threadLocalDemo;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class AnotherDemo {
    
        static ThreadLocal<String> threadLocal = new ThreadLocal<>();
    
        public static void main(String[] args) throws InterruptedException {
            //创建一个仅有一个线程的线程池(模拟在一个线程中的前后操作)
            ExecutorService executorService = Executors.newFixedThreadPool(1);
            //线程提交任务:线程中设置ThreadLocal变量并打印
            executorService.submit(() -> {
                threadLocal.set("hello");
                System.out.println(Thread.currentThread().getName()+":"+threadLocal.get());
            });
            //线程延迟1s提交任务:获取ThreadLocal变量并打印
            Thread.sleep(1000);
            executorService.submit(() -> {
                //修改变量
                threadLocal.set("world");
                System.out.println(Thread.currentThread().getName()+":"+threadLocal.get());
                //删除变量
                threadLocal.remove();
            });
            //线程延迟1s提交任务:获取ThreadLocal变量并打印
            Thread.sleep(1000);
            executorService.submit(() -> {
                System.out.println(Thread.currentThread().getName()+":"+threadLocal.get());
            });
            executorService.shutdown();
        }
    }

    打印结果如下:

    pool-1-thread-1:hello
    pool-1-thread-1:world
    pool-1-thread-1:null
  • 相关阅读:
    LUOGU P4113 [HEOI2012]采花
    LUOGU P4251 [SCOI2015]小凸玩矩阵
    bzoj 3230 相似子串——后缀数组
    bzoj 4453 cys就是要拿英魂!——后缀数组+单调栈+set
    洛谷 5061 秘密任务——二分图染色
    bzoj 4104 [Thu Summer Camp 2015]解密运算——思路
    bzoj 4319 cerc2008 Suffix reconstruction——贪心构造
    poj 3415 Common Substrings——后缀数组+单调栈
    CF 504E Misha and LCP on Tree——后缀数组+树链剖分
    bzoj 4278 [ONTAK2015]Tasowanie——后缀数组
  • 原文地址:https://www.cnblogs.com/silenceshining/p/15564077.html
Copyright © 2011-2022 走看看