并发编程基础之ThreadLocal
一:概念
在多线程并发访问的情况下,为了解决线程安全,一般我们会使用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的更多相关文章
- Java并发编程系列-(1) 并发编程基础
1.并发编程基础 1.1 基本概念 CPU核心与线程数关系 Java中通过多线程的手段来实现并发,对于单处理器机器上来讲,宏观上的多线程并行执行是通过CPU的调度来实现的,微观上CPU在某个时刻只会运 ...
- python中并发编程基础1
并发编程基础概念 1.进程. 什么是进程? 正在运行的程序就是进程.程序只是代码. 什么是多道? 多道技术: 1.空间上的复用(内存).将内存分为几个部分,每个部分放入一个程序,这样同一时间在内存中就 ...
- Java并发编程基础
Java并发编程基础 1. 并发 1.1. 什么是并发? 并发是一种能并行运行多个程序或并行运行一个程序中多个部分的能力.如果程序中一个耗时的任务能以异步或并行的方式运行,那么整个程序的吞吐量和可交互 ...
- TCP与UDP比较 以及并发编程基础知识
一.tcp比udp真正可靠地原因 1.为什么tcp比udp传输可靠地原因: 我们知道在传输数据的时候,数据是先存在操作系统的缓存中,然后发送给客户端,在客户端也是要经过客户端的操作系统的,因为这个过程 ...
- 并发-Java并发编程基础
Java并发编程基础 并发 在计算机科学中,并发是指将一个程序,算法划分为若干个逻辑组成部分,这些部分可以以任何顺序进行执行,但与最终顺序执行的结果一致.并发可以在多核操作系统上显著的提高程序运行速度 ...
- Java并发编程基础三板斧之Semaphore
引言 最近可以进行个税申报了,还没有申报的同学可以赶紧去试试哦.不过我反正是从上午到下午一直都没有成功的进行申报,一进行申报 就返回"当前访问人数过多,请稍后再试".为什么有些人就 ...
- Java高并发编程基础三大利器之CountDownLatch
引言 上一篇文章我们介绍了AQS的信号量Semaphore<Java高并发编程基础三大利器之Semaphore>,接下来应该轮到CountDownLatch了. 什么是CountDownL ...
- Java并发编程--基础进阶高级(完结)
Java并发编程--基础进阶高级完整笔记. 这都不知道是第几次刷狂神的JUC并发编程了,从第一次的迷茫到现在比较清晰,算是个大进步了,之前JUC笔记不见了,重新做一套笔记. 参考链接:https:// ...
- day20-多并发编程基础(一)
重新写一下吧,系统奔溃了,以前写的完全没了,悲催,今日主要写进程 1. 进程的理论知识 2. python中的进程操作 开始今日份整理,加油,你是最胖的!!! 1. 进程的理论知识 1.1 操作系统的 ...
随机推荐
- TypeScript语法学习--变量的声明
JavaScript里相对较新的变量声明方式是let和const.let在很多方面与var是相似的,但是可以帮助大家避免在JavaScript里常见一些问题. const是对let的一个增强,它能阻止 ...
- HTML5上传下载
前言 HTML5 中提供的文件API在前端中有着丰富的应用,上传.下载.读取内容等在日常的交互中很常见.而且在各个浏览器的兼容也比较好,包括移动端,除了 IE 只支持 IE10 以上的版本.想要更好地 ...
- JSAP101
JSAP101 1.DOM 1)文档对象模型 文档:把一个Html文件看成一个文档,所以把这个文档看成一个对象.XML文件也可以看成一个文件.XML侧重于存储数据,html主要以展示为主.一个页面就是 ...
- MUI学习03-滚动图(幻灯片)及菜单项(九宫格)
<!--标准mui.css-->引入CSS:<link rel="stylesheet" href="../css/mui.min.css"& ...
- /etc/passwd /etc/group /etc/shadow 文件的格式说明
/etc/passwd 存放账户信息: root:x:0:0:root:/root:/bin/bashjianing:x:1011:100::/home/jianing:/bin/bashuserna ...
- shell字符串的用法
shell字符串的用法 注意:shell4.2和shell4.1会有差别,较低版本的shell可能不支持某些功能 获取字符串长度:${#string} 获取子串: 注:(左边的第一个字符是用 0 表示 ...
- IDEA攻略合辑
AS使用lombok注解报错:Annotation processors must be explicitly declared now. The following dependencies on ...
- [Python设计模式] 第15章 如何兼容各种DB——抽象工厂模式
github地址:https://github.com/cheesezh/python_design_patterns 题目 如何让一个程序,可以灵活替换数据库? 基础版本 class User(): ...
- Java 并发编程(二)对象的不变性和安全的公布对象
一.不变性 满足同步需求的还有一种方法是使用不可变对象(Immutable Object). 到眼下为止,我们介绍了很多与原子性和可见性相关的问题,比如得到失效数据.丢失更新操作或光查到某个对象处于不 ...
- 飞思卡尔单片机P&E开发工具硬件及软件
原文链接: http://blog.sina.com.cn/s/blog_8ebff8d7010121tm.html 1.HC(S)08系列 开发机硬件:USB-ML-12 CYCLONE PRO U ...