并发编程基础之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 操作系统的 ...
随机推荐
- 创建xml文件、解析xml文件
1.创建XML文件: import codecs import xml.dom.minidom doc=xml.dom.minidom.Document() print doc root=do ...
- “百度杯”CTF比赛 九月场---123
右键查看源代码 然后构造user.php,显示空白,源码也是空白,既然上边说用户名,密码了,参考大佬的博客,放文件user.php.bak这是备份文件,一打开上边全是用户名,有戏,爆破 添加字典,也就 ...
- 安装oracle11g不能启动图形化界面
问题:安装oracle11g时出现xhost: unable to open display "192.168.2.12:0.0".打不开图形化界面等. 终极解决方法:1.使用X ...
- linux命令之kill篇
作业四:查询firewall进程,然后杀死 [root@localhost 桌面]# ps -aux |grep firewall root 772 0.0 2.0 327912 2 ...
- JSAP101
JSAP101 1.DOM 1)文档对象模型 文档:把一个Html文件看成一个文档,所以把这个文档看成一个对象.XML文件也可以看成一个文件.XML侧重于存储数据,html主要以展示为主.一个页面就是 ...
- 邮轮ERP系统
近两年一直做邮轮旅游方面的系统开发,最近有点时间,就花了两三个月,开发了一套邮轮ERP. 感兴趣的同学可以给我留言(904308112@qq.com),一起交流学习.
- Deepin 15.4 挂载分区
硬盘是 500G,先前安装 Windows7 时,分了3个区,大小分别为 90G.100G.310G,现在用 Deepin 重装系统时,挂载情况如下: /dev/sda1 分区作为 /(挂载点),类型 ...
- MAC终端密钥登录自动输入密码
升级MAC系统后,发现用于MAC终端ssh服务器的登录脚本无法正常执行了,表现为:需要手动输入密钥密码,于是重新整理一下,恢复正常,在此记录一下: #!/usr/bin/expect -fspawn ...
- linux go环境安装和基本项目结构
最近项目中要用到Go语言,所以简单总结一下安装和配置,Go这个语言本身就限定了很多规范,比如项目设置,编程风格等,开发中就不需要再因为各种规范问题纠结了,直接用官方规定的能避免很多坑,下面直接切正题, ...
- TensorFlow保存和载入模型
首先定义一个tf.train.Saver类: saver = tf.train.Saver(max_to_keep=1) 其中,max_to_keep参数设定只保存最后一个参数,默认值是5,即保存最后 ...