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程序员所需要掌握的核心知识.觉得内容不错 ...
随机推荐
- oracle表空间中PCTFREE, PCTUSED, INITRANS, MAXTRANX参数的解释
1. PCTFREE 要形容一个 BLOCK 的运作,我们可以把一个 BLOCK 想成一个水杯.侍者把水倒入放在我们面前的水杯,要多满呢,我们要求他倒 9 分满好了,这时候 PCTFREE 代表着设定 ...
- vue 过渡状态
vue的过渡系统提供了非常多简单的方法设置进入.离开和列表的动效.那么对于数据元素本身的动效呢,例: 数字和运算 颜色的显示 svg节点的位置 元素的大小和其他的属性 所有的原始数字都被事先存储起来, ...
- linux学习笔记18--文件/chmod/chown/chgrp
文件类型与扩展名: Linux文件类型和Linux文件的文件名所代表的意义是两个不同的概念.我们通过一般应用程序而创建的比如file.txt.file.tar.gz ,这些文件虽然要用不同的程序来打开 ...
- Hive学习笔记——Hive中的分桶
对于每一个表(table)或者分区, Hive可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分.Hive也是针对某一列进行桶的组织.Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记 ...
- 第一百三十六节,JavaScript,封装库--事件绑定
JavaScript,封装库--事件绑定 在函数库添加两个函数 添加事件绑定函数 删除事件绑定函数 添加事件绑定函数 /** addEvent()函数库函数,跨浏览器添加事件绑定,注意:传入事件名称时 ...
- Python相对完美的URL拼接函数
首先说下什么叫URL拼接,我们有这么一个HTML片段: <a href="../../a.html">click me</a> 做为一只辛苦的爬虫,我们 ...
- Material design之Views and Shadows
Views and Shadows: elevation是构成控件阴影的基本属性.通过设置较高的Z值可以接受更大的阴影,阴影只能投射到Z=0的平面上. View Elevation 控件的Z值,是由两 ...
- structure machine learning projects 课程笔记
orthogonalization/ one metric train.dev/test 划分 开发集和测试集一定来自同一分布 onthe same distribution Human leve ...
- Linux经常使用命令(十八) - find概述
Linux下find命令在文件夹结构中搜索文件,并运行指定的操作.Linux下find命令提供了相当多的查找条件,功能非常强大.由于find具有强大的功能,所以它的选项也非常多.当中大部分选项都值得我 ...
- std::function(3)
#include <functional> #include <string> #include <iostream> using namespace std; v ...