一:概念

在多线程并发访问的情况下,为了解决线程安全,一般我们会使用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

  

最新文章

  1. 在UWP中页面滑动导航栏置顶
  2. Your account already has a valid iOS Distribution certificate!
  3. 在github上写个人简历——先弄个主页
  4. Ext.GridPanel 用法总结(一)—— Grid基本用法
  5. JS初学之-自定义属性(索引值)
  6. 为什么选择 Yeoman 及 Yeoman 的安装
  7. PHP7正式版测试,性能惊艳!
  8. Android项目的图标
  9. Oracle EBS-SQL (WIP-14):检查车间需求与BOM差异对照.sql
  10. 用MVC+EF快速弄出一个CRUD
  11. 新版elasticsearch的插件安装
  12. 如何将多个C文件链接在一起----Makefile编写及make指令
  13. 【题解】Luogu P4867 Gty的二逼妹子序列
  14. JAVA高级篇(四、JVM垃圾回收和调优)
  15. 富可视M310刷机包 MIUIV5 红米开发版 闪光 美化 稳定
  16. rename 表
  17. norbert-构建服务器集群感知的 Java 应用程序
  18. Visual Assist X 10.8.2042的Crack破解补丁. 2014.06.25 (General release.)
  19. Java Spring-注解进行属性注入
  20. cuDNN下载地址和指南

热门文章

  1. 移动端根元素(html)的设置
  2. ajax请求json中的数据
  3. Java中Double类型的精确计算
  4. fixed和sticky
  5. JS膏集04
  6. jQuery 学习(2)——jQuery选择器
  7. 将 Smart 构件发布到 Maven 中央仓库
  8. centos修改主机名 root@后面的名字
  9. 机器学习中Batch Size、Iteration和Epoch的概念
  10. C# System.IO.FileMode