ThreadLocal 示例
ThreadLocal, 从字面意思上看是本地线程. 但实际上它是一个线程本地变量.它的功能就是为每一个使用该变量的线程都提供一个变量值的副本, 从而使得不会与其他线程的副本冲突. 与使用synchronized解决同步问题一样的作用, 区别是synchronized是通过使用加锁的方式来实现的,而ThreadLocal是通过其内部定义的一个Map来存放每一个线程的变量副本来实现的.
看下面的例子, 通过多个线程来设置Student的age属性:
package threadLocal;
public class Student {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student [age=" + age + ", name=" + name + "]";
}
}
有同步问题的代码:
package threadLocal;
import java.util.Random;
public class ThreadDemo implements Runnable {
private static Student stu = new Student();
@Override
public void run() {
accessStudent();
}
private void accessStudent() {
try {
Random r = new Random();
int age =r.nextInt(100);
stu.setAge(age);
System.out.println(Thread.currentThread().getName() + ":" + stu);
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName() + ":" + "after 3 second:" + stu);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ThreadDemo demo = new ThreadDemo();
for(int i=0;i<10;i++) {
Thread a = new Thread(demo, "a"+i);
a.start();
}
}
} 结果: a4:Student [age=66, name=null]
a0:Student [age=87, name=null]
a1:Student [age=66, name=null]
a2:Student [age=66, name=null]
a3:Student [age=63, name=null]
a5:Student [age=63, name=null]
a8:Student [age=73, name=null]
a9:Student [age=14, name=null]
a6:Student [age=6, name=null]
a7:Student [age=45, name=null]
a3:after 3 second:Student [age=45, name=null]
a1:after 3 second:Student [age=45, name=null]
a0:after 3 second:Student [age=45, name=null]
a4:after 3 second:Student [age=45, name=null]
a9:after 3 second:Student [age=45, name=null]
a8:after 3 second:Student [age=45, name=null]
a5:after 3 second:Student [age=45, name=null]
a7:after 3 second:Student [age=45, name=null]
a2:after 3 second:Student [age=45, name=null]
a6:after 3 second:Student [age=45, name=null]
使用synchronized解决:
package threadLocal;
import java.util.Random;
public class ThreadDemo implements Runnable {
private static Student stu = new Student();
@Override
public void run() {
accessStudent();
}
private synchronized void accessStudent() {
try {
Random r = new Random();
int age =r.nextInt(100);
stu.setAge(age);
System.out.println(Thread.currentThread().getName() + ":" + stu);
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName() + ":" + "after 3 second:" + stu);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ThreadDemo demo = new ThreadDemo();
for(int i=0;i<10;i++) {
Thread a = new Thread(demo, "a"+i);
a.start();
}
}
} 结果: a0:Student [age=86, name=null]
a0:after 3 second:Student [age=86, name=null]
a5:Student [age=14, name=null]
a5:after 3 second:Student [age=14, name=null]
a4:Student [age=31, name=null]
a4:after 3 second:Student [age=31, name=null]
a8:Student [age=58, name=null]
a8:after 3 second:Student [age=58, name=null]
a9:Student [age=5, name=null]
a9:after 3 second:Student [age=5, name=null]
a6:Student [age=10, name=null]
a6:after 3 second:Student [age=10, name=null]
a7:Student [age=22, name=null]
a7:after 3 second:Student [age=22, name=null]
a2:Student [age=37, name=null]
a2:after 3 second:Student [age=37, name=null]
a3:Student [age=92, name=null]
a3:after 3 second:Student [age=92, name=null]
a1:Student [age=41, name=null]
a1:after 3 second:Student [age=41, name=null]
使用ThreadLocal解决:
package threadLocal;
import java.util.Random;
public class ThreadLocalDemo implements Runnable {
private static ThreadLocal<Student> studentLocal = new ThreadLocal<Student>();
@Override
public void run() {
accessStudent();
}
private void accessStudent() {
Student s = getStudent();
Random r = new Random();
int age = r.nextInt(100);
s.setAge(age);
System.out.println(Thread.currentThread().getName() + ":" + s);
try {
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName() + ":" + "after 3 second:" + s);
} catch (Exception e) {
e.printStackTrace();
}
}
private Student getStudent() {
Student s = studentLocal.get();
if (s == null) {
s = new Student();
studentLocal.set(s);
}
return s;
}
public static void main(String[] args) {
ThreadLocalDemo demo = new ThreadLocalDemo();
for(int i=0;i<10;i++) {
Thread a = new Thread(demo, "a"+i);
a.start();
}
}
}
结果:
a9:Student [age=72, name=null]
a3:Student [age=10, name=null]
a8:Student [age=24, name=null]
a7:Student [age=5, name=null]
a1:Student [age=65, name=null]
a2:Student [age=39, name=null]
a6:Student [age=5, name=null]
a5:Student [age=61, name=null]
a4:Student [age=47, name=null]
a0:Student [age=41, name=null]
a9:after 3 second:Student [age=72, name=null]
a8:after 3 second:Student [age=24, name=null]
a3:after 3 second:Student [age=10, name=null]
a7:after 3 second:Student [age=5, name=null]
a1:after 3 second:Student [age=65, name=null]
a2:after 3 second:Student [age=39, name=null]
a5:after 3 second:Student [age=61, name=null]
a6:after 3 second:Student [age=5, name=null]
a0:after 3 second:Student [age=41, name=null]
a4:after 3 second:Student [age=47, name=null]
ThreadLocal 示例的更多相关文章
- java并发:线程同步机制之ThreadLocal
1.简述ThreadLocal ThreadLocal实例通常作为静态的私有的(private static)字段出现在一个类中,这个类用来关联一个线程.ThreadLocal是一个线程级别的局部变量 ...
- ThreadLocal 笔记
synchronized 同步的机制可以解决多线程并发问题,这种解决方案下,多个线程访问到的都是同一份变量的内容.为了防止在多线程访问的过程中,可能会出现的并发错误.不得不对多个线程的访问进行同步,这 ...
- 【Java线程安全】 — ThreadLocal
[用法] 首先明确,ThreadLocal是用空间换时间来解决线程安全问题的,方法是各个线程拥有自己的变量副本. 既然如此,那么是涉及线程安全,必然有一个共享变量,我给大家声明一个: public c ...
- 14、Java并发性和多线程-Java ThreadLocal
以下内容转自http://ifeve.com/java-theadlocal/: Java中的ThreadLocal类可以让你创建的变量只被同一个线程进行读和写操作.因此,尽管有两个线程同时执行一段相 ...
- java中threadlocal的理解
[TOC] #java中threadlocal的理解##一.threadlocal的生命周期和ThreadLocalMap的生命周期可以吧TreadLocal看做是一个map来使用,只不过这个map是 ...
- 深度揭秘Netty中的FastThreadLocal为什么比ThreadLocal效率更高?
阅读这篇文章之前,建议先阅读和这篇文章关联的内容. 1. 详细剖析分布式微服务架构下网络通信的底层实现原理(图解) 2. (年薪60W的技巧)工作了5年,你真的理解Netty以及为什么要用吗?(深度干 ...
- 硬核剖析ThreadLocal源码,面试官看了直呼内行
工作面试中经常遇到ThreadLocal,但是很多同学并不了解ThreadLocal实现原理,到底为什么会发生内存泄漏也是一知半解?今天一灯带你深入剖析ThreadLocal源码,总结ThreadLo ...
- Java并发编程实战笔记—— 并发编程2
1.ThreadLocal Java中的ThreadLocal类可以让你创建的变量只被同一个线程进行读和写操作.因此,尽管有两个线程同时执行一段相同的代码,而且这段代码又有一个指向同一个ThreadL ...
- 【搞定 Java 并发面试】面试最常问的 Java 并发进阶常见面试题总结!
本文为 SnailClimb 的原创,目前已经收录自我开源的 JavaGuide 中(61.5 k Star![Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识.觉得内容不错 ...
随机推荐
- mysql用事务插入数据
Connection conn = null; try { conn = queryRunner.getDataSource().getConnection(); ConnectionUtils.se ...
- 初探csrf学习笔记
以下是学习了对CSRF的理解,大家切勿作为标准,如有出错请告之! 严禁转载.不想拿自己刚学到的知识去[误人子弟]之所以写出来是让自己巩固和增加理解,他日对此文有不当之处自会修改. [00x1]csrf ...
- flume+kafka+storm打通过程
0.有的地方我已经整理成脚本了,有的命令是脚本里面截取的 1.启动hadoop和yarn $HADOOP_HOME/sbin/start-dfs.sh;$HADOOP_HOME/sbin/start- ...
- 基于Spring框架的简单多数据源切换解决办法
基于Spring框架的简单多数据源切换解决办法 Spring框架JDBC包提供了一个抽象类AbstractRoutingDataSource提供了动态切换数据库的基础方法.我们仅仅需要实现一个简单的数 ...
- 《Netty in action》目录修复版本分享
最近阅读了Netty in action一书.深感外国友人的书籍编写能力强大.作者由简入深.精简描述了Netty的相关知识,如何使用等等. 本来想翻译一下的.尝试着翻译了一点之后.发现非常痛苦啊.ps ...
- apply 判定变量类型
js 数据类型 6大类:object ,undefined,boolean,string,number,null,但是有时候我们经常要更准确的判断,比如,是数组,还是单例... 那么就用apply吧, ...
- nginx健康节点检查nginx_upstream_check_module 淘宝的upstream_check进行nginx后端检查 tengine
Nginx实战系列之功能篇----后端节点健康检查 2015-01-18 22:35 5007人阅读 评论(0) 收藏 举报 分类: Nginx(28) 目录(?)[+] 公司前一段对业务 ...
- easyui -grid每列绑定tooltip
/**用法:*/function doCellTip() { $('#dg').datagrid('doCellTip', { 'max-width': '100px' });} /** * 扩展两个 ...
- struts2中,Action通过什么方式获得用户从页面输入的数据,又是通过什么方式把其自身的数据传给视图的?
struts2中,Action通过什么方式获得用户从页面输入的数据,又是通过什么方式把其自身的数据传给视图的? 解答: 1)可以直接通过与表单元素相同名称的数据成员(需要存在符合命名规范set和get ...
- spark(1.1) mllib 源码分析(三)-朴素贝叶斯
原创文章,转载请注明: 转载自http://www.cnblogs.com/tovin/p/4042467.html 本文主要以mllib 1.1版本为基础,分析朴素贝叶斯的基本原理与源码 一.基本原 ...