ThreadLocal类可以理解为ThreadLocalVariable(线程局部变量),提供了get与set等访问接口或方法,这些方法为每个使用该变量的线程都存有一份独立的副本,因此get总是返回当前执行线程在调用set时设置的最新值。可以将ThreadLocal<T>视为 包含了Map<Thread,T>对象,保存了特定于该线程的值。

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

模拟ThreadLocal

    import java.util.Collections;
    import java.util.HashMap;
    import java.util.Map;
     
    public class SimpleThreadLocal<T> {
    private Map<Thread, T> valueMap = Collections
    .synchronizedMap(new HashMap<Thread, T>());
     
    public void set(T newValue) {
    valueMap.put(Thread.currentThread(), newValue); // ①键为线程对象,值为本线程的变量副本
    }
     
    public T get() {
    Thread currentThread = Thread.currentThread();
    T o = valueMap.get(currentThread); // ②返回本线程对应的变量
    if (o == null && !valueMap.containsKey(currentThread)) { // ③如果在Map中不存在,放到Map中保存起来。
    o = initialValue();
    valueMap.put(currentThread, o);
    }
    return o;
    }
     
    public void remove() {
    valueMap.remove(Thread.currentThread());
    }
     
    protected T initialValue() {
    return null;
    }
    }
实用ThreadLocal
    class Count {
    private SimpleThreadLocal<Integer> count = new SimpleThreadLocal<Integer>() {
    @Override
    protected Integer initialValue() {
    return 0;
    }
    };
     
    public Integer increase() {
    count.set(count.get() + 1);
    return count.get();
    }
     
    }
     
    class TestThread implements Runnable {
    private Count count;
     
    public TestThread(Count count) {
    this.count = count;
    }
     
    @Override
    public void run() {
    // TODO Auto-generated method stub
    for (int i = 1; i <= 3; i++) {
    System.out.println(Thread.currentThread().getName() + "\t" + i
    + "th\t" + count.increase());
    }
    }
    }
     
    public class TestThreadLocal {
    public static void main(String[] args) {
    Count count = new Count();
    Thread t1 = new Thread(new TestThread(count));
    Thread t2 = new Thread(new TestThread(count));
    Thread t3 = new Thread(new TestThread(count));
    Thread t4 = new Thread(new TestThread(count));
    t1.start();
    t2.start();
    t3.start();
    t4.start();
    }
    }

输出
Thread-0    1th    1
Thread-0    2th    2
Thread-0    3th    3
Thread-3    1th    1
Thread-1    1th    1
Thread-1    2th    2
Thread-2    1th    1
Thread-1    3th    3
Thread-3    2th    2
Thread-3    3th    3
Thread-2    2th    2

Thread-2    3th    3  

Java并发编程之ThreadLocal类的更多相关文章

  1. Java并发编程之ThreadLocal解析

    本文讨论的是JDK 1.8中的ThreadLocal ThreadLocal概念 ThreadLocal多线程间并发访问变量的解决方案,为每个线程提供变量的副本,用空间换时间. ThreadLocal ...

  2. Java并发编程之ThreadLocal源码分析

    ## 1 一句话概括ThreadLocal<font face="微软雅黑" size=4>  什么是ThreadLocal?顾名思义:线程本地变量,它为每个使用该对象 ...

  3. Java并发编程之CAS

    CAS(Compare and swap)比较和替换是设计并发算法时用到的一种技术.简单来说,比较和替换是使用一个期望值和一个变量的当前值进行比较,如果当前变量的值与我们期望的值相等,就使用一个新值替 ...

  4. Java并发编程之CAS第一篇-什么是CAS

    Java并发编程之CAS第一篇-什么是CAS 通过前面几篇的学习,我们对并发编程两个高频知识点了解了其中的一个—volatitl.从这一篇文章开始,我们将要学习另一个知识点—CAS.本篇是<凯哥 ...

  5. Java并发编程之CAS二源码追根溯源

    Java并发编程之CAS二源码追根溯源 在上一篇文章中,我们知道了什么是CAS以及CAS的执行流程,在本篇文章中,我们将跟着源码一步一步的查看CAS最底层实现原理. 本篇是<凯哥(凯哥Java: ...

  6. Java并发编程之CAS第三篇-CAS的缺点及解决办法

    Java并发编程之CAS第三篇-CAS的缺点 通过前两篇的文章介绍,我们知道了CAS是什么以及查看源码了解CAS原理.那么在多线程并发环境中,的缺点是什么呢?这篇文章我们就来讨论讨论 本篇是<凯 ...

  7. Java并发编程之set集合的线程安全类你知道吗

    Java并发编程之-set集合的线程安全类 Java中set集合怎么保证线程安全,这种方式你知道吗? 在Java中set集合是 本篇是<凯哥(凯哥Java:kagejava)并发编程学习> ...

  8. 并发编程之ThreadLocal

    并发编程之ThreadLocal 前言 当多线程访问共享可变数据时,涉及到线程间同步的问题,并不是所有时候,都要用到共享数据,所以就需要线程封闭出场了. 数据都被封闭在各自的线程之中,就不需要同步,这 ...

  9. 并发编程之ThreadLocal源码分析

    当访问共享的可变数据时,通常需要使用同步.一种避免同步的方式就是不共享数据,仅在单线程内部访问数据,就不需要同步.该技术称之为线程封闭. 当数据封装到线程内部,即使该数据不是线程安全的,也会实现自动线 ...

随机推荐

  1. 记录一下C#+Oracle批量插入的一个方法

    public bool insertOracle(DataTable dataTable, string sql) // Oracle sql 查询的是表头 { string ConnStr = Wi ...

  2. IOS通过PushSharp开源框架发送推送

    1,首先生成推送证书: openssl x509 -in aps_developer_identity.cer -inform DER -out aps_developer_identity.pem ...

  3. H5+Boostrap的音乐播放器

    H5+Boostrap做简单的音乐播放器 前言:这个是综合一下我最近在学的东西做的小Demo,到实际使用还有距离,但是用来练手巩固知识点还是不错的,最近在二刷JS书和Boostrap.css的源码,做 ...

  4. [TYVJ] P1055 沙子合并

    沙子合并 描述 Description     设有N堆沙子排成一排,其编号为1,2,3,…,N(N<=300).每堆沙子有一定的数量,可以用一个整数来描述,现在要将这N堆沙子合并成为一堆,每次 ...

  5. 定时任务:Java中Timer和TimerTask的使用

    java.util.Timer定时器,实际上是个线程,定时调度所拥有的TimerTasks. 一个TimerTask实际上就是一个拥有run方法的类,需要定时执行的代码放到run方法体内,TimerT ...

  6. case then 的用法 貌似case then不支持别名

    set ANSI_NULLS ONset QUOTED_IDENTIFIER ONgo ALTER PROC [dbo].[usp_SRV_GetALLRelativeProject]@Service ...

  7. UESTC_秋实大哥打游戏 2015 UESTC Training for Data Structures<Problem H>

    H - 秋实大哥打游戏 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Subm ...

  8. 【转】【经典算法】——KMP,深入讲解next数组的求解

    前言 之前对kmp算法虽然了解它的原理,即求出P0···Pi的最大相同前后缀长度k:但是问题在于如何求出这个最大前后缀长度呢?我觉得网上很多帖子都说的不是很清楚,总感觉没有把那层纸戳破,后来翻看算法导 ...

  9. 在Linux下如何创建LVM及LVM创建过程

    Linux LVM创建过程:(我用的是Centos6.8) 一.准备工作: LVM可以的创建可以在系统安装的过程中创建,也可以在安装完系统之后再创建建,都是可以的,我的是在系统安装完之后创建的,具体的 ...

  10. php 原理相关

    [PHP 运行方式(PHP SAPI介绍)] http://www.phpddt.com/php/php-sapi.html [PHP内核探索:从SAPI接口开始]http://www.nowamag ...