• 研究ThreadLocal类


    依旧不想说话..........我就是看到了ThreadLocal就写了。

    参考:深入研究java.lang.ThreadLocal类 大大写的很好!我就挑了我喜欢的写了(✿◕‿◕✿)

    一、ThreadLocal是啥啥

      ▶ThreadLocal是线程局部变量,它为每一个使用该变量的线程提供一个变量值的副本,每一个线程都可以独立的改变自己的副本,而不会和其他线程的副本发生冲突。

      ▶从线程的角度看,每个线程都保持一个对其线程局部变量副本的引用,只要线程是活动的并且ThreadLocal实例是可访问的,在线程消失之后,其线程局部实例的所有副本都会被垃圾回收(除非其他地方还有引用)。

      ▶对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而不互相影响。

      ThreadLocal类中维护一个Map,用于存储每一个线程的变量副本,Map中元素的键为线程对象,而值为对应线程的变量副本。

    二、API

      ThreadLocal() 创建一个线程本地变量。

      T get() 返回此线程局部变量的当前线程副本中的值。

      void set(T value) 将此线程局部变量的当前线程副本中的值设置为指定值。

      protected T initialValue() 返回此线程局部变量的当前线程的初始值。

      void remove() 移除此线程局部变量的值。

     一个小例子(Student类就不写了........name,age加上get 和set 方法

    public class ThreadLocalDemo implements Runnable {
        private static final ThreadLocal studentLocal = new ThreadLocal();
    
        public static void main(String[] args) {
            ThreadLocalDemo td = new ThreadLocalDemo();
            Thread t1 = new Thread(td,"a");
            Thread t2 = new Thread(td,"b");
            t1.start();
            t2.start();
    
        }
    
    
        @Override
        public void run() {
            accessStudent();
        }
    
        public void accessStudent(){
            String currentThreadName = Thread.currentThread().getName();
            System.out.println(currentThreadName + " is Running");
    
            Random random = new Random();
            int age = random.nextInt(20);
            Student student = getStudent();
            student.setAge(age);
            System.out.println("thread " + currentThreadName + "first read age is: " + student.getAge());
    
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            System.out.println("thread " + currentThreadName + "second reead age is: " + student.getAge());
        }
    
        protected Student getStudent(){
            //获取本地线程变量并强制转换为Student类型
            Student student = (Student) studentLocal.get();
            //线程首次执行此方法的时候studentLocal.get() 肯定为null
            if(student == null){
                student = new Student();
                studentLocal.set(student);
            }
            return student;
        }
    
    
    }

    结果就是两个线程的age不一样,但在不同时刻打印的值是一样的。

    三、总结

      ThreadLocal使用场合主要解决多线程中数据因并发产生不一致问题,不能使用原子类型,只能使用Object类型。

      Synchronized是利用锁的机制,某一时刻只能被一个线程访问,而ThreadLocal为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并不是同一个对象。

  • 相关阅读:
    appium常见问题03_appium脚本报错selenium.common.exceptions.WebDriverException
    如何保存android app日志
    appium常见问题02_android内嵌H5页(webview)如何定位
    appium常见问题01_android筛选下拉框无法定位问题
    数字类型
    计算机基础
    HTML5学习笔记
    spring boot-hello world
    C#开发移动应用系列(4.调用系统应用,以及第三方应用(调用与被调用))
    C#开发移动应用系列(3.使用照相机扫描二维码+各种基础知识)
  • 原文地址:https://www.cnblogs.com/MoisAbby/p/8458930.html
Copyright © 2020-2023  润新知