【ThreadLocal模式】线程上的全局变量
来源:互联网 发布:女留学生遇害 知乎 编辑:程序博客网 时间:2024/06/11 15:12
运用ThreadLocal模式的场景:
1.频繁创建生命周期短暂的实例(或者实例化代价昂贵)导致性能低下
2.需要线程安全,使用‘synchronized’线程同步同样导致性能低下
以下是Tim Cull的博文“SimpleDateFormat: Performance Pig”解决满足这一需求采用ThreadLocal模式的案列
Tim Cull 写道:
Tim Cull碰到一个SimpleDateFormat带来的严重的性能问题,该问题主要有SimpleDateFormat引发,创建一个 SimpleDateFormat实例的开销比较昂贵,解析字符串时间时频繁创建生命周期短暂的实例导致性能低下。即使将 SimpleDateFormat定义为静态类变量,貌似能解决这个问题,但是SimpleDateFormat是非线程安全的,同样存在问题,如果用 ‘synchronized’线程同步同样面临问题,同步导致性能下降(线程之间序列化的获取SimpleDateFormat实例)。
Tim Cull使用Threadlocal解决了此问题,对于每个线程SimpleDateFormat不存在影响他们之间协作的状态,为每个线程创建一个SimpleDateFormat变量的拷贝或者叫做副本
public class DateUtil { private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; @SuppressWarnings("rawtypes") private static ThreadLocal threadLocal = new ThreadLocal() { protected synchronized Object initialValue() { return new SimpleDateFormat(DATE_FORMAT); } }; public static DateFormat getDateFormat() { return (DateFormat) threadLocal.get(); } public static Date parse(String textDate) throws ParseException { return getDateFormat().parse(textDate); } }
下面做了 静态计数器(/单例模式) 和 ThreadLocal模式计数器 对比结果,证明ThreadLocal模式下是线程安全的,每个线程都有自己的独立副本,线程内各个方法及层次都可以使用该变量,而不用再次实例化或者采用传参【比如Struts的ActionContext】。
public class Counter {public static Integer number =10;}
public class LocalCounter {public Integer number =10;private static ThreadLocal<LocalCounter> counter = new ThreadLocal<LocalCounter>(){protected synchronized LocalCounter initialValue(){return new LocalCounter();}};//初始需要覆盖初始化方法,不覆盖第一次调用get方法值为null,使用前需要先调set方法初始化public static LocalCounter getCounter() { return (LocalCounter) counter.get();}public static void setCounter(LocalCounter counterFrom){counter.set(counterFrom);}}
public class ThreadLocalStub extends Thread {public void run() {for (int i = 0; i < 2; i++) {LocalCounter localCounter = LocalCounter.getCounter();//当前使用时不用再次创建System.out.println("Thread[" + Thread.currentThread().getName()+ "],localCounter=" + localCounter.number++);System.out.println("Thread[" + Thread.currentThread().getName()+ "],Counter=" + Counter.number++);LocalCounter.setCounter(localCounter);} nextAdd();}private void nextAdd(){LocalCounter localCounter = LocalCounter.getCounter();//当前使用时不用再次创建,线程上共享System.out.println("Thread[" + Thread.currentThread().getName()+ "],localCounter=" + localCounter.number++);System.out.println("Thread[" + Thread.currentThread().getName()+ "],Counter=" + Counter.number++);LocalCounter.setCounter(localCounter);}}
public class ThreadLocalTest {public static void main(String[] args) {ThreadLocalStub testThread1 = new ThreadLocalStub();ThreadLocalStub testThread2 = new ThreadLocalStub();ThreadLocalStub testThread3 = new ThreadLocalStub();testThread1.start();testThread2.start();testThread3.start();}}运行结果:
Thread[Thread-0],localCounter=10
Thread[Thread-1],localCounter=10
Thread[Thread-0],Counter=10
Thread[Thread-1],Counter=11
Thread[Thread-1],localCounter=11
Thread[Thread-1],Counter=12
Thread[Thread-1],localCounter=12
Thread[Thread-1],Counter=13
Thread[Thread-2],localCounter=10
Thread[Thread-2],Counter=14
Thread[Thread-2],localCounter=11
Thread[Thread-2],Counter=15
Thread[Thread-2],localCounter=12
Thread[Thread-2],Counter=16
Thread[Thread-0],localCounter=11
Thread[Thread-0],Counter=17
Thread[Thread-0],localCounter=12
Thread[Thread-0],Counter=18
- 【ThreadLocal模式】线程上的全局变量
- 全局变量的线程安全性
- ThreadLocal模式的理解
- servlet线程安全问题——ThreadLocal模式
- java线程安全的ThreadLocal
- j2ee的线程安全--threadlocal
- 线程的私家小院儿:ThreadLocal
- 关于ThreadLocal模式的体会
- ThreadLocal模式的实现机理
- 【线程】 ThreadLocal
- Hibernate用ThreadLocal模式 (线程局部变量模式) 管理Session
- 线程局部变量ThreadLocal的认识
- ThreadLocal和线程同步机制的比较
- ThreadLocal 线程范围内的共享变量
- ThreadLocal实现线程范围内的数据共享
- ThreadLocal实现线程范围的共享变量
- ThreadLocal实现线程范围的共享变量
- ThreadLocal和线程同步机制的比较
- 关于GCC的__attribute__(constructor)
- linux c++线程池的实现
- 如何获得系统版本
- 自己写的解析FTP地址下协议,用户名,密码,路径的代码。。。体力活
- SharePoint Wiki Page 编辑内容保存时报错:you must specify a value for this required field
- 【ThreadLocal模式】线程上的全局变量
- linux下C实现线程池的源代码
- 清除UITableView底部多余的分割线
- 翻译】Building on Horizon
- 关于struts1中字符串和时间转化方式
- Visual C++中DDB与DIB位图编程全攻略
- IOS之tableview 实现动态加载图片
- hibernate对象关系映射
- 托福评分标准