• ThreadLocal 多线程并发,数据隔离


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

    本质:在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。

    优点:既实现多线程并发,游兼顾数据的安全性。

    区别:Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。

    示例:

    public class Student {
        private int age = 0;   //年龄
     
        public int getAge() {
            return this.age;
        }
     
        public void setAge(int age) {
            this.age = age;
        }
    }
     
     
    public class ThreadLocalDemo implements Runnable {
        //创建线程局部变量studentLocal,在后面你会发现用来保存Student对象
        private final static ThreadLocal studentLocal = new ThreadLocal();
     
        public static void main(String[] agrs) {
            ThreadLocalDemo td = new ThreadLocalDemo();
            Thread t1 = new Thread(td, "a");
            Thread t2 = new Thread(td, "b");
            t1.start();
            t2.start();
        }
     
        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(100);
            System.out.println("thread " + currentThreadName + " set age to:" + age);
     
            //获取一个Student对象,并将随机数年龄插入到对象属性中
            Student student = getStudent();
            student.setAge(age);
            System.out.println("thread " + currentThreadName + " first read age is:" + student.getAge());

            try {
                Thread.sleep(500);
             }
            catch (InterruptedException ex) {
                ex.printStackTrace();
             }

            System.out.println("thread " + currentThreadName + " second read age is:" + student.getAge());
        }
     
        protected Student getStudent() {
            //获取本地线程变量并强制转换为Student类型
            Student student = (Student) studentLocal.get();
            //线程首次执行此方法的时候,studentLocal.get()肯定为null
            if (student == null) {
                //创建一个Student对象,并保存到本地线程变量studentLocal中
          student = new Student();
                studentLocal.set(student);
            }
            return student;
        }
    }
     
     
    结果:
    a is running! 
    thread a set age to:76 
    b is running! 
    thread b set age to:27 
    thread a first read age is:76 
    thread b first read age is:27 
    thread a second read age is:76 
    thread b second read age is:27 
     
     
  • 相关阅读:
    @getMapping与@postMapping
    springcloud--入门
    Linux(centos6.5)mysql安装
    基于用户Spark ALS推荐系统(转)
    hadoop MapReduce在Linux上运行的一些命令
    Navicat连接阿里云轻量级应用服务器mysql
    HDFS操作笔记
    线程池的5种创建方式
    分布式共享锁的程序逻辑流程
    推荐系统常用数据集
  • 原文地址:https://www.cnblogs.com/wutianlong/p/5383364.html
Copyright © 2020-2023  润新知