锁定老帖子 主题:ThreadLocal示例
精华帖 (2) :: 良好帖 (13) :: 新手帖 (13) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-09-08
liujun999999 写道 pengzhoushuo 写道 liujun999999 写道 我觉得效率是否真的有提高?
每个线程第一次调用ThreadLocal的时候会调用initialValue,也就是说其实每个线程还是创建了一个SimpleDateFormat啊 呵呵,是static变量,不会每次都调用initialValue,初始化的时候一次而已。 查看ThreadLocal类的doc 引用 protected T initialValue() 返回此线程局部变量的当前线程的“初始值”。线程第一次使用 get() 方法访问变量时将调用此方法,但如果线程之前调用了 set(T) 方法,则不会对该线程再调用 initialValue 方法。通常,此方法对每个线程最多调用一次,但如果在调用 get() 后又调用了 remove(),则可能再次调用此方法。 该实现返回 null;如果程序员希望线程局部变量具有 null 以外的值,则必须为 ThreadLocal 创建子类,并重写此方法。通常将使用匿名内部类完成此操作。 返回: 返回此线程局部变量的初始值 并不是创建ThreadLocal对象的时候调用一次 sorry,确实是我看错了,应该是单个线程只new一次,每个线程还是会各new一次的 |
|
返回顶楼 | |
发表时间:2010-09-08
是个好点子 threadLocal 这个类还是蛮有创意的 在hibernate中 的openSession的实现就是使用了threadLocal实现的
重要的是思想 看怎么用 |
|
返回顶楼 | |
发表时间:2010-09-08
不错,典型的以空间换时间的实现,值得借鉴。
|
|
返回顶楼 | |
发表时间:2010-09-09
import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; public class T { private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; private static ThreadLocal threadLocal = new ThreadLocal() { protected synchronized Object initialValue() { System.out.println("-----"); return new SimpleDateFormat(DATE_FORMAT); } }; public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { public void run() { T t = new T(); t.threadLocal.get(); } }); Thread t2 = new Thread(new Runnable() { public void run() { T t = new T(); t.threadLocal.get(); } }); Thread t3 = new Thread(new Runnable() { public void run() { T t = new T(); t.threadLocal.get(); } }); t1.start(); t2.start(); t3.start(); } } 输出 三次,为什么多次实例化了new SimpleDateFormat(DATE_FORMAT); ? 怎么以空间换时间了? |
|
返回顶楼 | |
发表时间:2010-09-09
import java.text.SimpleDateFormat; public class T { private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; private static ThreadLocal threadLocal = new ThreadLocal() { protected synchronized Object initialValue() { System.out.println("-----"); return new SimpleDateFormat(DATE_FORMAT); } }; public static void main(String[] args) { T tt1 = new T(); T tt2 = new T(); T tt3 = new T(); tt1.threadLocal.get(); tt2.threadLocal.get(); tt3.threadLocal.get(); } } 这样是输出了一次,在单线程里有效,与多线程无关吧? |
|
返回顶楼 | |
发表时间:2010-09-09
pouyang 写道 import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; public class T { private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; private static ThreadLocal threadLocal = new ThreadLocal() { protected synchronized Object initialValue() { System.out.println("-----"); return new SimpleDateFormat(DATE_FORMAT); } }; public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { public void run() { T t = new T(); t.threadLocal.get(); } }); Thread t2 = new Thread(new Runnable() { public void run() { T t = new T(); t.threadLocal.get(); } }); Thread t3 = new Thread(new Runnable() { public void run() { T t = new T(); t.threadLocal.get(); } }); t1.start(); t2.start(); t3.start(); } } 输出 三次,为什么多次实例化了new SimpleDateFormat(DATE_FORMAT); ? 怎么以空间换时间了? 每个线程第一次获取都会初始化一次,你的实践验证能力很好,可能我开始描述的不是很清晰; 每一个线程初始化一次,每一个线程自身维护一个map,空间上占用内存较多,但不需要同步节约了时间; |
|
返回顶楼 | |
发表时间:2010-09-09
不好意思刚代码好像有点问题,但是这样还是输出三次
import java.text.DateFormat; import java.text.SimpleDateFormat; public class T { private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; private static ThreadLocal threadLocal = new ThreadLocal() { protected synchronized Object initialValue() { System.out.println("-----"); return new SimpleDateFormat(DATE_FORMAT); } }; public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { public void run() { T t = new T(); DateFormat df = (DateFormat) threadLocal.get(); if(df==null){ df = new SimpleDateFormat(DATE_FORMAT); threadLocal.set(df); } //threadLocal.get(); } }); Thread t2 = new Thread(new Runnable() { public void run() { T t = new T(); DateFormat df = (DateFormat) threadLocal.get(); if(df==null){ df = new SimpleDateFormat(DATE_FORMAT); threadLocal.set(df); } // threadLocal.get(); } }); Thread t3 = new Thread(new Runnable() { public void run() { T t = new T(); DateFormat df = (DateFormat) threadLocal.get(); if(df==null){ df = new SimpleDateFormat(DATE_FORMAT); threadLocal.set(df); } //threadLocal.get(); } }); t1.start(); t2.start(); t3.start(); } } 说明每个线程的 threadLocal.get(); 得到的都是null |
|
返回顶楼 | |
发表时间:2010-09-09
pouyang 写道 不好意思刚代码好像有点问题,但是这样还是输出三次
import java.text.DateFormat; import java.text.SimpleDateFormat; public class T { private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; private static ThreadLocal threadLocal = new ThreadLocal() { protected synchronized Object initialValue() { System.out.println("-----"); return new SimpleDateFormat(DATE_FORMAT); } }; public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { public void run() { T t = new T(); DateFormat df = (DateFormat) threadLocal.get(); if(df==null){ df = new SimpleDateFormat(DATE_FORMAT); threadLocal.set(df); } //threadLocal.get(); } }); Thread t2 = new Thread(new Runnable() { public void run() { T t = new T(); DateFormat df = (DateFormat) threadLocal.get(); if(df==null){ df = new SimpleDateFormat(DATE_FORMAT); threadLocal.set(df); } // threadLocal.get(); } }); Thread t3 = new Thread(new Runnable() { public void run() { T t = new T(); DateFormat df = (DateFormat) threadLocal.get(); if(df==null){ df = new SimpleDateFormat(DATE_FORMAT); threadLocal.set(df); } //threadLocal.get(); } }); t1.start(); t2.start(); t3.start(); } } 说明每个线程的 threadLocal.get(); 得到的都是null 每一次get的时候都调用getMap,返回一个map,判断map是否为null,如果为null,初始化; 因为每次获取的是线程自身的map,这个map第一次使用的时候肯定为null,调用初始化,输出了三次---------------,这么解释不知道您能否理解; ThreadLocalMap getMap(Thread t) { return t.threadLocals; } |
|
返回顶楼 | |
发表时间:2010-09-09
引用 每个线程第一次获取都会初始化一次,你的实践验证能力很好,可能我开始描述的不是很清晰;
每一个线程初始化一次,每一个线程自身维护一个map,空间上占用内存较多,但不需要同步节约了时间; 那把那个SimpleDateFormat对象的 static 修饰符去掉多好, 写成这样SimpleDateFormat s = new SimpleDateFormat(DATE_FORMAT); 就不需要考虑同步了,而且还不用去new ThreadLocal() , 我的理解是用了ThreadLocal就可以跨类跨方法调用这个SimpleDateFormat 了(方法不用带参数)(robbin说的) 我是不是还没开窍啊。 |
|
返回顶楼 | |
发表时间:2010-09-09
pengzhoushuo 写道 pengjunwu 写道 不明白 如果format 有2种或者更多 怎么处理
String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; String DATE_FORMAT = "yyyy/MM/dd HH:mm:ss"; ..... 如果你有两个format,那就建多一个ThreadLocal变量呀,楼主想要表达的意思是说不要每次都new一个SimpleFormat,同个线程可以共享一个SimpleFormat。 我的意识是说 DATE_FORMAT 不能作为参数动态来创建SimpleFormat。 |
|
返回顶楼 | |