一:概念

在多线程并发访问的情况下,为了解决线程安全,一般我们会使用synchronized关键字,如果并发访问量不是很大,可以使用synchronized,

但是如果数据量比较大,我们可以考虑使用ThreadLocal,顾名思义,就是线程的本地存储,对于类中的成员变量,如果多个线程同时访问

就会存在线程安全问题,ThreadLocal提供给我们不同于synchronized的另外一种思路,就是把变量值在每个线程存储副本

如下示例:

/**
*
*/
package com.hlcui.main; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* @author Administrator
*
*/
public class ThreadLocalDemo { //保留变量在线程中的副本
private ThreadLocal<String> threadLocal = new ThreadLocal<String>(); private void set(String name) {
threadLocal.set(name);
} private String get() {
return threadLocal.get();
} public static void main(String[] args) {
final ThreadLocalDemo demo = new ThreadLocalDemo(); ExecutorService executors = Executors.newFixedThreadPool(2);
executors.execute(new Runnable() {
@Override
public void run() {
demo.set("tom");
String threadName = Thread.currentThread().getName();
System.out.println(threadName+":::"+demo.get());
}
}); executors.execute(new Runnable() {
@Override
public void run() {
demo.set("jack");
String threadName = Thread.currentThread().getName();
System.out.println(threadName+":::"+demo.get());
}
}); executors.shutdown();
}
}

  

运行结果:

pool-1-thread-1:::tom
pool-1-thread-2:::jack

  

通过结果可以看出同一个实例的同一个方法,不同的线程获取的结果是不一样的。

示例二:

测试5个线程计数:

/**
*
*/
package com.hlcui.main; import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; /**
* @author Administrator
*
*/
public class ThreadDemo2 {
public static void main(String[] args) {
ExecutorService executors = Executors.newFixedThreadPool(5);
for (int i = 0; i < 5; i++) {
executors.execute(new ThreadHolder(i));
}
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
executors.shutdown();
} } class ThreadHolder implements Runnable { private final int id; ThreadHolder(int i) {
this.id = i;
} private static ThreadLocal<Integer> tl = new ThreadLocal<Integer>() {
Random r = new Random(47);
public synchronized Integer initialValue() {
return r.nextInt(100);
}
}; public static void increment() {
tl.set(tl.get() + 1);
} @Override
public void run() {
System.out.println(this);
ThreadHolder.increment();
System.out.println(this);
} public String toString() {
return "id:::"+id+", "+tl.get();
} }

  

运行结果:

id:::0, 58
id:::1, 55
id:::2, 93
id:::0, 59
id:::2, 94
id:::1, 56
id:::3, 61
id:::3, 62
id:::4, 61
id:::4, 62

  

并发编程基础之ThreadLocal的更多相关文章

  1. Java并发编程系列-(1) 并发编程基础

    1.并发编程基础 1.1 基本概念 CPU核心与线程数关系 Java中通过多线程的手段来实现并发,对于单处理器机器上来讲,宏观上的多线程并行执行是通过CPU的调度来实现的,微观上CPU在某个时刻只会运 ...

  2. python中并发编程基础1

    并发编程基础概念 1.进程. 什么是进程? 正在运行的程序就是进程.程序只是代码. 什么是多道? 多道技术: 1.空间上的复用(内存).将内存分为几个部分,每个部分放入一个程序,这样同一时间在内存中就 ...

  3. Java并发编程基础

    Java并发编程基础 1. 并发 1.1. 什么是并发? 并发是一种能并行运行多个程序或并行运行一个程序中多个部分的能力.如果程序中一个耗时的任务能以异步或并行的方式运行,那么整个程序的吞吐量和可交互 ...

  4. TCP与UDP比较 以及并发编程基础知识

    一.tcp比udp真正可靠地原因 1.为什么tcp比udp传输可靠地原因: 我们知道在传输数据的时候,数据是先存在操作系统的缓存中,然后发送给客户端,在客户端也是要经过客户端的操作系统的,因为这个过程 ...

  5. 并发-Java并发编程基础

    Java并发编程基础 并发 在计算机科学中,并发是指将一个程序,算法划分为若干个逻辑组成部分,这些部分可以以任何顺序进行执行,但与最终顺序执行的结果一致.并发可以在多核操作系统上显著的提高程序运行速度 ...

  6. Java并发编程基础三板斧之Semaphore

    引言 最近可以进行个税申报了,还没有申报的同学可以赶紧去试试哦.不过我反正是从上午到下午一直都没有成功的进行申报,一进行申报 就返回"当前访问人数过多,请稍后再试".为什么有些人就 ...

  7. Java高并发编程基础三大利器之CountDownLatch

    引言 上一篇文章我们介绍了AQS的信号量Semaphore<Java高并发编程基础三大利器之Semaphore>,接下来应该轮到CountDownLatch了. 什么是CountDownL ...

  8. Java并发编程--基础进阶高级(完结)

    Java并发编程--基础进阶高级完整笔记. 这都不知道是第几次刷狂神的JUC并发编程了,从第一次的迷茫到现在比较清晰,算是个大进步了,之前JUC笔记不见了,重新做一套笔记. 参考链接:https:// ...

  9. day20-多并发编程基础(一)

    重新写一下吧,系统奔溃了,以前写的完全没了,悲催,今日主要写进程 1. 进程的理论知识 2. python中的进程操作 开始今日份整理,加油,你是最胖的!!! 1. 进程的理论知识 1.1 操作系统的 ...

随机推荐

  1. NOIP考试各种技巧!!

    考前时间利用对考生起着至关重要的作用,不容忽视! 一.考前几分钟时间,往往能决定成败,所以一定要做好心态调整.不要去想结果,只看过程,努力了就一定不会白费.二.在别人紧张.坐立不安的时候,你不妨把时间 ...

  2. 【C语言程序】让用户输入十个数,用冒泡排序法从小到大排序

    #include <stdio.h> #define N 10 void swap(int*a,int*b); int main(int argc, char *argv[]) {  in ...

  3. 关于字符串 --java

    这是在杭电上做一道水题时发现的,挺不错,写下了分享一下 http://acm.hdu.edu.cn/showproblem.php?pid=2072 这里我用了两种方法,参考大佬的,一个是list实现 ...

  4. cookies和session

      基于cookies做用户验证时,敏感信息不适合放在cookies中 cookies保存在客户浏览器端的键值对 session保存在服务器端的键值对(依赖于cookies),把用户浏览器中的cook ...

  5. 使用Spring AOP实现MySQL读写分离

    spring aop , mysql 主从配置 实现读写分离,下来把自己的配置过程,以及遇到的问题记录下来,方便下次操作,也希望给一些朋友带来帮助.mysql主从配置参看:http://blog.cs ...

  6. javagc日志详解

    https://blog.csdn.net/aliveTime https://plumbr.io/blog/garbage-collection/understanding-garbage-coll ...

  7. Visual Studio 2015 没显示可用的.Net Framework版本

    安装了VS 2015企业版, 然后在创建工程的时候遇到了一个问题: 当我选择Framework版本时候, 列表是空的, 如下图所示: 是生成工具出现了问题,所以尝试又安装了下 "Micros ...

  8. 用SSH登录远程的机器,在远程机器上执行本地机器上的脚本

    假设本地的机器IP为10.245.111.90,我们想要在10.245.111.93上执行一个保存在10.245.111.90上的脚本. 经过测试通过的命令如下: ssh root@10.245.11 ...

  9. WIN10系统提示无法使用内置管理员账户打开XXX应用程序怎么办

    重装了系统之后,只保留Administrator账户,结果打开程序的时候回弹出这个提示   运行,输入secpol.msc   本地策略-安全选项,启用下面这个,然后重启计算机      

  10. zigw 和 nanoWatch, libudev.so 和 XMR 挖矿程序查杀记录

    最近这两天以来,服务器一致声音很响.本来以为有同事在运行大的程序,结果后来发现持续很长时间都是这样,并没有停的样子.后来查了一下,发现有几个可疑进程导致,干掉之后,果然服务器静悄悄了. 但是,问题并没 ...