【Java多线程与并发库】6.ThreadLocal类及应用技巧
来源:互联网 发布:linux jdk下载 64位 编辑:程序博客网 时间:2024/05/29 03:30
之前我们了解了实现线程范围内数据共享的机制,接下来我们
可以使用JDK5提供的ThreadLocal类,来实现线程范围内数据共享。
ThreadLocal类其实就类似于我们上一次创建的Map。
我们创建一个测试类,来使用ThreadLocal类实现线程范围内数据共享:
我们的类A和类B每次都从线程中获取data值打印,为了保证每次打印的数据是该线程的数据,
可以使用JDK5提供的ThreadLocal类,来实现线程范围内数据共享。
ThreadLocal类其实就类似于我们上一次创建的Map。
我们创建一个测试类,来使用ThreadLocal类实现线程范围内数据共享:
我们的类A和类B每次都从线程中获取data值打印,为了保证每次打印的数据是该线程的数据,
类A和类B的数据都从ThreadLocal中获取。
- package cn.edu.hpu.test;
- import java.util.Random;
- public class ThreadTest7 {
- private static Random dandom=new Random();
- private static ThreadLocal<Integer> x=new ThreadLocal<Integer>();
- public static void main(String[] args) {
- for(int i=0;i<2;i++){
- new Thread(new Runnable(){
- public void run() {
- int data=dandom.nextInt();
- System.out.println(Thread.currentThread().getName()
- +"放入数据:"+data);
- x.set(data);
- new A().get();
- new B().get();
- }
- }).start();
- }
- }
- static class A{
- public void get(){
- System.out.println("A 从"+Thread.currentThread().getName()
- +"中取的数据:"+x.get());
- }
- }
- static class B{
- public void get(){
- System.out.println("B 从"+Thread.currentThread().getName()
- +"中取的数据:"+x.get());
- }
- }
- }
实现了每个线程中的数据共享在每个线程自己的范围内。线程之间的数据不会混杂在一起。
如果有N个变量需要做到线程范围内数据共享,应该如何做到?
一个ThreadLocal只能放一个变量,我们可以使用多个ThreadLocal来实现,
如果共享的数据量过大,我们就把这些数据放在一个对象中,然后在ThreadLocal中
存储这一个对象。
- package cn.edu.hpu.test;
- import java.util.Random;
- public class ThreadTest7 {
- private static Random dandom=new Random();
- private static ThreadLocal<MyThreadScopeData> MyThreadScopeData=new ThreadLocal<MyThreadScopeData>();
- public static void main(String[] args) {
- for(int i=0;i<2;i++){
- new Thread(new Runnable(){
- public void run() {
- int data=dandom.nextInt();
- System.out.println(Thread.currentThread().getName()
- +"放入数据:"+data);
- MyThreadScopeData ScopeData=new MyThreadScopeData();
- ScopeData.setName("name"+data);
- ScopeData.setAge(data);
- MyThreadScopeData.set(ScopeData);
- new A().get();
- new B().get();
- }
- }).start();
- }
- }
- static class A{
- public void get(){
- System.out.println("A 从"+Thread.currentThread().getName()
- +"中取的数据:"+MyThreadScopeData.get().getName()
- +MyThreadScopeData.get().getAge());
- }
- }
- static class B{
- public void get(){
- System.out.println("A 从"+Thread.currentThread().getName()
- +"中取的数据:"+MyThreadScopeData.get().getName()
- +MyThreadScopeData.get().getAge());
- }
- }
- }
- class MyThreadScopeData{
- private String name;
- private int age;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- }
结果:
这样就可以在线程范围内共享N中数据了。
上面的设计其实不够好,但是要设计更加优雅一点,不要看到我们使用ThreadLocal的痕迹:
- package cn.edu.hpu.test;
- import java.util.Random;
- public class ThreadTest7 {
- private static Random dandom=new Random();
- public static void main(String[] args) {
- for(int i=0;i<2;i++){
- new Thread(new Runnable(){
- public void run() {
- int data=dandom.nextInt();
- System.out.println(Thread.currentThread().getName()
- +"放入数据:"+data);
- MyThreadScopeData.getThreadInstance().setName("name"+data);
- MyThreadScopeData.getThreadInstance().setAge(data);
- new A().get();
- new B().get();
- }
- }).start();
- }
- }
- static class A{
- public void get(){
- System.out.println("A 从"+Thread.currentThread().getName()
- +"中取的数据:"+MyThreadScopeData.getThreadInstance().getName()
- +MyThreadScopeData.getThreadInstance().getAge());
- }
- }
- static class B{
- public void get(){
- System.out.println("A 从"+Thread.currentThread().getName()
- +"中取的数据:"+MyThreadScopeData.getThreadInstance().getName()
- +MyThreadScopeData.getThreadInstance().getAge());
- }
- }
- }
- class MyThreadScopeData{
- private MyThreadScopeData(){}
- public static MyThreadScopeData getThreadInstance(){
- MyThreadScopeData instance=map.get();
- if(instance==null){
- instance=new MyThreadScopeData();
- map.set(instance);
- }
- return instance;
- }
- private static ThreadLocal<MyThreadScopeData> map =new ThreadLocal<MyThreadScopeData>();
- private String name;
- private int age;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- }
这里,我们调用MyThreadScopeData的getThreadInstance方法,就可以取得
与当前线程相关的实例对象。
虽然线程结束后也可以自动释放相关的ThreadLocal变量,但是为了优化内存,
我们的ThreadLocal要在线程结束的时候注销,可以调用ThreadLocal.clear()方法。
出处:http://blog.csdn.net/acmman/article/details/52794523
0 0
- 【Java多线程与并发库】6.ThreadLocal类及应用技巧
- 【Java多线程与并发库】6.ThreadLocal类及应用技巧
- 【java并发】ThreadLocal类以及应用技巧
- 【张孝祥并发课程笔记】05:ThreadLocal类及应用技巧
- Java多线程与并发应用-(5)-如何优雅的使用ThreadLocal类
- 多线程06_张孝祥-ThreadLocal类及应用技巧
- ThreadLocal类及应用技巧
- ThreadLocal类及应用技巧
- Java多线程与并发库高级应用
- Java多线程与并发库高级应用
- Java多线程与并发库高级应用
- Java多线程与并发库高级应用
- Java--servlet + ThreadLocal解决多线程并发问题及实例
- 【Java多线程与并发库】05 线程范围内共享变量ThreadLocal
- Java并发ThreadLocal类
- 【java多线程与并发库】--- 定时器的应用
- 视频专辑:张孝祥 Java多线程与并发库高级应用
- Java多线程与并发库高级应用之线程池
- The POM for is missing, no dependency information available
- 深入理解乐观锁与悲观锁
- 2 javascript中变量、作用域和内存问题
- 如何在资源管理器中恢复“最近文件夹”
- leetcode 299. Bulls and Cows
- 【Java多线程与并发库】6.ThreadLocal类及应用技巧
- 如何修改Recovery的字符串资源(修改显示字体颜色和大小)
- export aborted becauser fatal lint errors were found . these are listed in the lint view,Either fix
- datagrid 行点击事件
- Oracle触发器备份表数据
- 第八周 OJ练习-2
- 题目1074:对称平方数【数位拆解】
- java注解详解(注解项目实战)
- 后台调用前台方法(能使用jquery的函数)