• 018 ThreadLocal实现线程安全


    一 .概述

    在之前我们讨论过线程安全性的问题,我们通过加锁或者使用无锁来保证线程安全.

      当然无锁的性能会变得更好.但是他们的实质的核心都是保证对访问的资源的原子性.

      那我们回忆一下线程安全性问题的发生的条件:

      [1]多线程并发

      [2]共享资源

      [3]对共享资源的非原子性操作

    我们如果将共享资源打破掉,那么我们是否也能保证线程安全呢?

      答案是肯定的,ThreadLoacl就能帮助我们实现线程级别的局部变量.


    二 .ThreadLocal的定义

      [1] get() : 获取值

      [2]set() : 设置值

      [3]remove() : 移除值

      现在我们演示一下ThreadLocal的用法,它定义了线程级别的局部变量.

    public class ThreadLocalTest {
        private final ThreadLocal<Integer> local = new ThreadLocal<Integer>();
    
        public ThreadLocalTest() {
            local.set(0);
        }
    
        public static void main(String[] args) {
            ThreadLocalTest test = new ThreadLocalTest();
            test.local.set(0);
            
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("子线程的值为:" + test.local.get());
                }
    
            }).start();
    
            // 主线程的线程栈中有了local,现在为0
            System.out.println("主线程的local的值为:" + test.local.get());
        }
    
    }

    我们创建了一个含有ThreadLocal的成员变量的对象,然后修改它的值为0.然后从主线程和子线程之中分别打印这个变量,我们发现结果如下:  

    主线程的local的值为:0
    子线程的值为:null

      子线程的值为null,说明子线程中发生了拷贝.子线程和主线程之中的变量并不是共享的.


    三 . 解析

      我们在前面看见了ThreadLocal的基本使用,ThreadLocal可以帮助我们实现线程的变量的存储.

        比如在我们的Servlet之中,本身模型就是多线程模型.

        现在我们可以使用ThreadLocal帮助我们存储数据.

  • 相关阅读:
    遇到的两个问题
    项目分析(map复习)
    while小问题
    二级指针
    映射文件实现进程通信
    struct {0}初始化
    用boost共享内存实现进程通信的例子
    mongo二维数组操作
    项目分析(channelid是如果产生的)
    string为什么可以写入共享内存
  • 原文地址:https://www.cnblogs.com/trekxu/p/9004728.html
Copyright © 2020-2023  润新知