线程范围内的共享数据(二)
2013-04-22 13:37
375 查看
ThreadLocal可以很方便的实现线程范围内的共享变量,ThreadLocal类就相当于一个Map。下面具体看这个类如何使用:
1-1 利用ThreadLocal实现线程范围内的共享变量
程序运行的结果如下:
上面的代码的整体思路:创建一个对象——放数据——取数据。代码组织的相当的糟糕,有没有一种优雅的实现实现方面呢?看下面的代码.
对代码1-1的改善,实现线程范围内的共享变量
程序运行的结果:
每一请求(每一个线程),有一个容器对象,这个容器对象存放与这个请求有关的所有数据,struts2中会有这种思想。
1-1 利用ThreadLocal实现线程范围内的共享变量
import java.util.Hashtable; import java.util.Map; import java.util.Random; /* 每个线程拥有自己独立的数据 一个ThreadLocal代表一个变量,故其中只能放一个数据。 */ public class ThreadLocalTest {//三个模块中的一个; private static ThreadLocal<Integer> x=new ThreadLocal<Integer>();//x变量名 //ThreadLocal里边存放MyThreadScopeData数据 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() { @Override public void run() { int data=new Random().nextInt(); System.out.println(Thread.currentThread().getName() +"has put data :"+data); x.set(data);//往当前线程中放数据,与当前线程相关的,不是全局的 MyThreadScopeData myData=new MyThreadScopeData();//new一个对象MyThreadScopeData() myData.setName("name"+data);//往myData里边存放数据 myData.setAge(data); MyThreadScopeData.set(myData);//存数据 new A().get(); new B().get(); } }){}.start(); } } static class A{ public void get(){ int data=x.get();//取与当前线程有关的数据 System.out.println("A from "+Thread.currentThread().getName() +" get data :"+data); MyThreadScopeData myData=MyThreadScopeData.get();//取数据,包括name和age System.out.println("A from "+Thread.currentThread().getName() +"getmyData :"+myData.getName()+","+ myData.getAge()); } } static class B{ public void get(){ int data=x.get(); System.out.println("B from "+Thread.currentThread().getName() +" get data :"+data); } } } 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; } }
程序运行的结果如下:
上面的代码的整体思路:创建一个对象——放数据——取数据。代码组织的相当的糟糕,有没有一种优雅的实现实现方面呢?看下面的代码.
对代码1-1的改善,实现线程范围内的共享变量
import java.util.HashMap; import java.util.Map; import java.util.Random; public class ThreadLocalTest { private static ThreadLocal<Integer> x = new ThreadLocal<Integer>(); 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(){ @Override public void run() { int data = new Random().nextInt(); System.out.println(Thread.currentThread().getName() + " has put data :" + data); x.set(data); //得到与本线程有关的实力对象,在设置值 MyThreadScopeData.getThreadInstance().setName("name" + data); MyThreadScopeData.getThreadInstance().setAge(data); new A().get(); new B().get(); } }).start(); } } static class A{ public void get(){ int data = x.get(); System.out.println("A from " + Thread.currentThread().getName() + " get data :" + data); MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();//得到与本线程有关的实例对象,在设置值 System.out.println("A from " + Thread.currentThread().getName() + " getMyData: " + myData.getName() + "," + myData.getAge()); } } static class B{ public void get(){ int data = x.get(); System.out.println("B from " + Thread.currentThread().getName() + " get data :" + data); MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();//得到与本线程有关的实例对象,在设置值 System.out.println("B from " + Thread.currentThread().getName() + " getMyData: " + myData.getName() + "," + myData.getAge()); } } } class MyThreadScopeData{//将实体转化成单例 private MyThreadScopeData(){}//第一件事:构造方法私有化,让其它的没法创建它的实例对象 public static /*synchronized*/ MyThreadScopeData getThreadInstance(){ //利用静态方法,得到实例对象,synchronized时,在饥汉模式下 MyThreadScopeData instance = map.get(); if(instance == null){//饥汉模式,只有第一次时创建(需要的时候创建),以后直接饭回instance instance = new MyThreadScopeData();//注意饥汉模式下,可能第一个线程来 //检查instance == null,就去创建(赋值),还没有返回的时候,CPU切换到第二个线程,第二个线程来检查, //创建(赋值),那么可能就出现,第二次赋值覆盖第一次赋值,所以要互斥synchronized map.set(instance);//将值存起来 } return instance;//返回实例对象 } //private static MyThreadScopeData instance = new MyThreadScopeData();//饱汉模式 //private static MyThreadScopeData instance = null;//饥汉模式 //装线程范围内的共享变量 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; } }
程序运行的结果:
每一请求(每一个线程),有一个容器对象,这个容器对象存放与这个请求有关的所有数据,struts2中会有这种思想。
相关文章推荐
- 多线程_线程范围内数据共享
- java多线程与线程并发四:线程范围内的共享数据
- 【多线程】-线程范围内共享数据的两种方式
- ThreadLocal实现线程范围内的数据共享
- 同一线程范围内数据共享
- 线程范围内的共享数据 ThreadLocal
- 多线程(四) 实现线程范围内模块之间共享数据及线程间数据独立(Map集合)
- 高级并发编程学习-线程范围内安全共享数据(使用ThreadLocal方式)
- Java死锁和线程范围内共享数据
- Java基础加强 线程范围内数据共享设计模式
- 线程范围内的共享数据(一)
- 线程范围内共享数据(二)
- 黑马程序员---java中如何实现线程范围内共享数据
- 多线程学习(四)-线程范围内共享数据
- 线程范围内的数据共享
- Java高并发编程:线程范围内共享数据
- 多线程之线程范围内的数据共享ThreadLocal
- 线程范围内共享数据(一)
- 线程范围内共享数据
- 线程范围内数据共享