运用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
分享到:
相关推荐
java ThreadLocal多线程专属的变量源码java ThreadLocal多线程专属的变量源码java ThreadLocal多线程专属的变量源码java ThreadLocal多线程专属的变量源码java ThreadLocal多线程专属的变量源码java ThreadLocal多...
今天小编就为大家分享一篇关于Hibernate用ThreadLocal模式(线程局部变量模式)管理Session,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
ThreadLocal 线程微本地变量 及 源码分析
1、问题 通常复杂的处理流程中,我们会使用一些异步处理的手段,... ThreadLocal threadLocal = new ThreadLocal(); threadLocal.set("A"); System.out.println(Thread.currentThread().getName()+"-getThreadLocal:
设计模式及ThreadLocal详细讲解资料,想要学习java或者提升自己技术的同学可以下载观看
主要介绍了Java多线程编程之ThreadLocal线程范围内的共享变量,本文讲解了ThreadLocal的作用和目的、ThreadLocal的应用场景、ThreadLocal的使用实例等,需要的朋友可以参考下
ThreadLocal则为每一个线程提供了一个变量副本,从而隔离了多个线程访问数据的冲突,ThreadLocal提供了线程安全的对象封装,下面我们就来详细了解一下吧
主要介绍了java 中ThreadLocal本地线程和同步机制的比较的相关资料,需要的朋友可以参考下
本例以序列号生成的程序为例,展示ThreadLocal的使用
关于线程变量ThreadLocal的介绍以及说明. 关于线程变量ThreadLocal的介绍以及说明. 关于线程变量ThreadLocal的介绍以及说明. 关于线程变量ThreadLocal的介绍以及说明. 关于线程变量ThreadLocal的介绍以及说明. ...
什么是ThreadLocal ThreadLocal一般称为线程本地变量,它是一种特殊的线程绑定...而ThreadLocal从本质上讲,无非是提供了一个“线程级”的变量作用域,它是一种线程封闭(每个线程独享变量)技术,更直白点讲,Thre
应用ThreadLocal进行多线程处理,经典小例子。可运行。
其实,它就是一个容器,用于存放线程的局部变量,我认为应该叫做 ThreadLocalVariable(线程局部变量)才对,真不理解为什么当初 Sun 公司的工程师这样命名。 早在 JDK 1.2 的时代,java.lang.ThreadLocal 就诞生了...
ThreadLocal保证一个类的实例变量在各个线程中都有一份单独的拷贝, 从而不会影响其他线程中的实例变量
导致JVM内存泄露的ThreadLocal详解 为什么要有ThreadLocal ThreadLocal的使用 实现解析 引发的内存泄漏分析 错误使用ThreadLocal导致 线程不安全分析
目录SimpleDateFormat诡异bug复现SimpleDateFormat诡异bug字符串日期转Date日期(parse)Date日期转String类型(format)SimpleDateFormat出现bug的原因如何解决SimpleDateFormat多线程安全问题局部变量使用...
目录一、背景介绍二、TestNG多线程详解2.1 TestNG多线程实现2.2 TestNG多线程效果演示三、ThreadLocal3.1 ThreadLocal概念3.2 具体实现 一、背景介绍 在使用Selenium+TestNG做WebUI自动化过程中,为了能够加快Web...
ThreadLocal