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程序员所需要掌握的核心知识.觉得内容不错 ...
随机推荐
- CentOS 7下Java的SecureRandom种子初始化失败解决办法
io.netty.util.internal.ThreadLocalRandom getInitialSeedUniquifierWARNING: Failed to generate a seed ...
- 浅谈配置文件:spring-servlet.xml(spring-mvc.xml) 与 applicationContext.xml
在搭建 spring mvc 的框架时,会有2个配置文件必不可少: spring-servlet.xml 和applicationContext.xml.第一次接触spring mvc的工程师可能会对 ...
- 初识md5碰撞与crc32碰撞
现在是晚上23:29.写这篇文章呢,是因为早些时候我胃疼,是因为凉导致的胃疼.凉呢喝了一些热水,喝完热水胃倒是不疼了,但是由于我喝的是茶叶开水,于是就导致失眠了.想来想去这漫漫长夜也没意思,于是就决定 ...
- idea传入HttpServletRequest时显示cannot resolve symbol的问题
在使用idea ide的时候,在控制器中我需要获取HttpServletRequest这个request对象,编译时出现cannot resolve symbol的问题,然后网上查找资料,这里记录一下 ...
- RTP时间戳
http://xingyunbaijunwei.blog.163.com/blog/static/7653806720126121014111/ ——————————————————————————— ...
- mysql 分数表实现排名
首先初始化一张表 DROP TABLE IF EXISTS `lq_wx_sign`; CREATE TABLE `lq_wx_sign` ( `id` ) unsigned NOT NULL AUT ...
- 什么是Web容器?
什么是Web容器? 解答:容器就是一种服务程序,在服务器一个端口就有一个提供相应服务的程序,而这个程序就是处理从客户端发出的请求,如JAVA中的Tomcat容器,ASP的IIS或PWS都是这样的容器.
- 网易研发project师(移动端游戏)—暑期实习生电面题目 2014年5月14日
2014年5月14日 暑期实习生电话面试: 首先自我介绍. 一.C++ 1.extern的使用方法 2.虚函数 3.强制转换 4.malloc和new的差别 二.计算机网络 1.TCP和UDP有什么差 ...
- DevExpress 控件使用技巧
DevExpress是非常主流的.NET控件,眼下全世界和中国都用非常多用户使用,只是因为是英文版,初次接触的同学可能会认为困难.这里就总结DevExpress常见的10个使用技巧. 1.TextEd ...
- html input accept类型
在上传文件的时候,需要限制指定的文件类型. <input type="file" accept="image/*" /> accept表示可以上传文 ...