6.ThreadLocal类及应用技巧
2015-07-10 11:10
239 查看
import java.util.Random; /** * ThreadLocal类及应用技巧 * ******************************************************************* * 每个线程调用全局ThreadLocal对象的set方法,就相当于往其内部的map中增加一条记录,key * 分别是各自的线程,values是各自的set方法穿进去的值。在线程结束时可以调用ThreadLocal.clear(); * 方法,这样会更快释放内存,不调用也可以,因为线程结束后也可以自动释放相关的ThreadLocal变量。 * 实现对ThreadLocal变量的封装,让外界不要直接操作ThreadLocal变量 * 对基本类型的数据的封装,这种应用相对少见。 * 对对象类型的数据的封装,比较常见,即让某个类针对不同线程分别创建一个独立的实例对象。 * 总结: * 一个ThreadLocal代表一个变量,故其中里只能放一个数据,你有两个变量都要线程范围内 * 共享,则要定义两个ThreadLocal对象。如果有一百个变量要线程共享呢?把ThreadLocal封装 * 到一个单例类中。 * * Struts2中的思想就是ThreadLocal模式 * * ******************************************************************* * 虚拟机挂掉的时候注册钩子通知 * Runtime->addShutdownHook(Thread hook) * @author LiTaiQing */ public class ThreadLocalTest { private static ThreadLocal<Integer> threadLocal = 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() + " get put data :" + data); threadLocal.set(data); //myThreadScopeData.set(new MyThreadScopeData("name"+data,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 = threadLocal.get(); System.out.println("A from" + Thread.currentThread().getName() + " get put data :" + data); //MyThreadScopeData myData = myThreadScopeData.get(); 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 = threadLocal.get(); System.out.println("B from" + Thread.currentThread().getName() + " get put data :" + data); //MyThreadScopeData myData = myThreadScopeData.get(); MyThreadScopeData myData = MyThreadScopeData.getThreadInstance(); System.out.println("B from" + Thread.currentThread().getName() + " getMyData :" + myData.getName()+","+myData.getAge()); } } } class MyThreadScopeData{ private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<MyThreadScopeData>(); //private static MyThreadScopeData instance = null;//new MyThreadScopeData(); private MyThreadScopeData(){}; /** * 这里可以不用synchronized,因为位于不同的线程内分别保存在ThreadLocal中 * @return */ public static /*synchronized*/ MyThreadScopeData getThreadInstance(){ MyThreadScopeData instance = map.get(); //这种方式容易出现多线程并发问题。所以最好采用饿汉模式 if(instance==null){ instance = new MyThreadScopeData(); map.set(instance); } return instance; } private String name; private int age; // public MyThreadScopeData(String name, int age) { // super(); // this.name = name; // this.age = 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; } }
相关文章推荐
- activemq 实战二 连接到ActiveMQ-Connecting to ActiveMQ
- 主流服务器中间件的环境下对BLOB类型字段的处理
- Python实现把json格式转换成文本或sql文件
- 系统公告模块,日志模块
- 5.线程范围内共享变量的概念与作用
- 在thinkphp框架模板中引用session
- nginx php上传大文件的设置(php-fpm)
- 2014阿里面经(转)
- android 与JS之间的交互
- linux grep和正则表达式
- Android ExpandableListView 一个小例子
- Freemarker如何写的简洁
- C语言之基本算法23—二分法求方程近似根
- 布局之三 -- TableLayout
- 广工anyview数据结构-04~06(乱码不贴)
- 4.传统线程同步通信技术
- MYSQL查询重复记录的方法
- activemq 实战三 了解连接器的URI-Understanding connector URIs
- ACM-简单的主题Ignatius and the Princess II——hdu1027
- 你知道什么是Grunt么?