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程序员所需要掌握的核心知识.觉得内容不错 ...
随机推荐
- JavaScript变量的生命周期
最近看国外经典教材的时候发现JavaScript与熟知的Java,C,C++都不同的特性,其中一个就是变量的生命周期. 1.在JavaScript中,对于for循环中定义的i变量,其生命周期在循环 ...
- azkaban入门中遇到的问题
执行时报错,后来发现他的配置文件中写了相对路径!!所以必须在他的根目录下执行,命令为 nohup bin/azkaban-web-start.sh 1>/tmp/azstd.out 2&g ...
- PYTHON中 赋值运算的若干问题总结
1.PYTHON中没有自增自减操作(++,——): 因为PYTHON中对于字符.数值等不可变的对象来说,自增自减没有意义. 2.PYTHON中l连接操作总是创建一个新对象. 举例: L=[1,2] M ...
- JS动态增加删除UL节点LI及相关内容示例
<ul id="ul"> <li id=1>11111111111111111<a href="javascript:del(1);&quo ...
- Bootstrap Multiselect 设置 option
$.ajax({ type: 'post', url: "helper/ajax_search.php", data: {models: decodeURIComponent(br ...
- C++ 类的多态五(多态的语法本质分析)
//多态的语法本质分析 #include<iostream> using namespace std; /* 三种易混淆的多态场景 */ class Point{ public: Poin ...
- jquery--递增--年份的选择
<select id="select_year"></select> <script> $(document).ready(function() ...
- 请用正则表达式匹配出QQ号(假设QQ号码为5—10位);
请用正则表达式匹配出QQ号(假设QQ号码为5—10位): 解答: ^ \d{5,10}$
- 目标跟踪之卡尔曼滤波---理解Kalman滤波的使用预测
Kalman滤波简介 Kalman滤波是一种线性滤波与预测方法,原文为:A New Approach to Linear Filtering and Prediction Problems.文章推导很 ...
- db2 设置表 not null
db2将原表列notnull属性修改为null属性的方法 今天把自己遇到的一个小问题跟大家分享一下如何修改db2数据库表中列的属性--将列的非空属性改为允许空的属性,修改数据表的某一列属性其实很简 ...