• JUC-ThreadLocal



    前言

    多线程访问同一个共享变量的时候也别容易出现并发问题,特别是在多线程需要对一个共享变量进行写入的时候。为了保证线程的安全,一般使用者在访问共享变量的时候需要进行适当的同步。如下图所示
    同步的措施一般是加锁,但是加锁显然加重了使用者的负担。那么有没有一种方式可以做到,当创建一个线程过后,每个线程对其访问的时候,访问的是自己线程的变量呢?其实ThreadLocal就可以做出这样一件事。

    ThreadLocal

    ThreadLocal是JDK提供的,它提供了线程本地变量,也就是说如果你创建了一个ThreadLocal变量,那么访问这个变量的每个线程都会有这个变量的一个本地副本。当多个线程操作这个变量的时候,实际上操作的是自己本地内存里面的变量,从而避免了线程安全问题。创建一个ThreadLocal变量后,每个线程都会复制一个变量到自己的本地内存,如下图所示:

    ThreadLocal测试

    代码如下:

    public class ThreadLocalTest {
    static void print(String str){
        System.out.println(str+":"+localVariable.get());
        localVariable.remove();
    }
        static ThreadLocal<String> localVariable=new ThreadLocal<String>();
    
        public static void main(String[] args) throws Exception{
    
            Thread threadone=new Thread(() -> {
              localVariable.set("threadone local variable");
                print("threadone");
                System.out.println("threadone remove after"+":"+localVariable.get());
            });
    
            Thread threadtwo=new Thread(() -> {
                localVariable.set("threadtwo local variable");
                print("threadtwo");
                System.out.println("threadtwo remove after"+":"+localVariable.get());
            });
    
            threadone.start();
            threadtwo.start();
    
        }
    
    }
    

    结果:

    ThreadLocal类结构

    ThreadLocal不支持继承性

    看一个栗子:

    public class ThreadLocaltest2 {
    public  static  ThreadLocal<String> threadLocal=new ThreadLocal<>();
    
        public static void main(String[] args) {
            threadLocal.set("hello world");
            Thread thread=new Thread(() -> {
                System.out.println("thread:"+threadLocal.get());
            });
            thread.start();
    
    
            System.out.println("main:"+threadLocal.get());
        }
    }
    

    输出结果:

    threadlocal变量是在main父线程中声明的,因此子线程thread是获取不到的。

    InheritableThreadLocal

    为了解决上诉问题,InheritableThreadLocal应运而生。

    public class InheritableThreadLocalTest {
        public  static  InheritableThreadLocal<String> threadLocal=new InheritableThreadLocal<>();
    
        public static void main(String[] args) {
            threadLocal.set("hello world");
            Thread thread=new Thread(() -> {
                System.out.println("thread:"+threadLocal.get());
            });
            thread.start();
    
    
            System.out.println("main:"+threadLocal.get());
        }
    
    
    }
    

    输出结果:

  • 相关阅读:
    webix datadable 分页重加载
    webix datatale 分頁加载两次
    webix .datatable 表格分页
    webix datatable 列头加tooltip
    webix.tree 修改图标
    webix icon 图标
    spring 模板发送邮件
    spring发QQ邮件
    严重: Context initialization failed org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [cn.itcast.javaee.springmvc.app06.HelloAction] for bean with name '/hello.action' de
    严重: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/springmvc-day01]]
  • 原文地址:https://www.cnblogs.com/xhj928675426/p/14462578.html
Copyright © 2020-2023  润新知