IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> ThreadLocal -> 正文阅读

[Java知识库]ThreadLocal

一、ThreadLocal应用

作用:
解决线程安全性问题。
常用方法:
set()
在当前线程范围内,设置一个值存储到ThreadLocal中,这个值仅对当前线程可见。相当于在当前线程范围内建立了副本。
get()
从当前线程范围内取出set方法设置的值.
remove()
移除当前线程中存储的值
withInitial
java8中的初始化方法
案例
ThreadLocalDemo.java

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadLocalDemo {
    //非线程安全的
    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private static ThreadLocal<DateFormat> dateFormatThreadLocal = new ThreadLocal<>();

    private static DateFormat getDateFormat() {
        DateFormat dateFormat = dateFormatThreadLocal.get(); //从当前线程的范围内获得一个DateFormat
        if (dateFormat == null) {
            dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //Thread.currentThread();
            dateFormatThreadLocal.set(dateFormat); //要在当前线程的范围内设置一个simpleDateFormat对象.
        }
        return dateFormat;
    }

    public static Date parse(String strDate) throws ParseException {
        return getDateFormat().parse(strDate);
    }

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 20; i++) {
            executorService.execute(() -> {
                try {
                    //sdf.parse("2021-05-30 20:12:20");
                    System.out.println(parse("2021-05-30 20:12:20"));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            });

        }
    }
}

ThreadLocalExample.java

public class ThreadLocalExample {
    //希望每一个线程获得的num都是0
//    private static int num=0;

    //全局用户信息的存储

    static ThreadLocal<Integer> local= ThreadLocal.withInitial(() -> 0);

    public static void main(String[] args) {
        Thread[] thread=new Thread[5];
        for(int i=0;i<5;i++){
            thread[i]=new Thread(()->{
                int num=local.get().intValue();
                local.set(num+=5);
                System.out.println(Thread.currentThread().getName()+" "+local.get());
            });
        }
        //local=null;
        for (int i = 0; i < 5; i++) {
            thread[i].start();
        }
    }
}

二、ThreadLocal原理分析

ThreadLocal原理猜想
能够实现线程的隔离,当前保存的数据,只会存储在当前线程范围内。
存储结构是键值对,key是ThreadLocal对象,value是当前线程设置的值。
ThreadLocal源码分析

public void set(T value) {
    Thread t = Thread.currentThread();
  // 如果当前线程已经初始化了map。
  // 如果没有初始化,则进行初始化。
    ThreadLocalMap map = getMap(t);
    if (map != null) //修改value
      map.set(this, value);
    else //初始化
      createMap(t, value);
 }
 
 ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
  table = new Entry[INITIAL_CAPACITY];  //默认长度为16的数组
  int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);  //计算数组下标
  table[i] = new Entry(firstKey, firstValue); //把key/value存储到i的位置.
  size = 1;
  setThreshold(INITIAL_CAPACITY);
}

private void set(ThreadLocal<?> key, Object value) {
  Entry[] tab = table;
  int len = tab.length;
  int i = key.threadLocalHashCode & (len-1); //计算数组下标()
  //线性探索.()
  for (Entry e = tab[i];
    e != null;
    e = tab[i = nextIndex(i, len)]) {
    ThreadLocal<?> k = e.get();
// i的位置已经存在了值, 就直接替换。
    if (k == key) {
      e.value = value;
      return;
   }
//如果key==null,则进行replaceStaleEntry(替换空余的数组)
    if (k == null) {
      replaceStaleEntry(key, value, i);
      return;
   }
 }
  tab[i] = new Entry(key, value);
  int sz = ++size;
  if (!cleanSomeSlots(i, sz) && sz >= threshold)
    rehash();
}

三、内存泄漏

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-05-05 11:04:09  更:2022-05-05 11:07:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:17:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码