精华帖 (2) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-05-25
http://www.iteye.com/topic/81936?page=1
以上是原贴. 本文只是针对原贴的补充. 对于ThreadLocal和synchronized的区别,请看下面的例子估计大家更能清楚认识.希望我能在kyluan原贴的基础上把这个区别说清楚. btw:这个例子是一个使用ThreadLocal不当的例子,请不要在项目中如此使用. public class TestThreadLocal { public static void main(String[] args) throws Exception { ThreadLocal myThreadLocal = new ThreadLocal(); StaffInfoVO staff1 = new StaffInfoVO(); staff1.setName("default"); staff1.setCount(new Integer(1)); for (int i = 0; i < 10; i++) { MyThread myt = new MyThread(staff1, myThreadLocal); Thread t1 = new Thread(myt); t1.setName("myThread" + i); t1.start(); } } public static class MyThread implements Runnable { private StaffInfoVO staff1; private ThreadLocal myThreadLocal; public MyThread(StaffInfoVO staff, ThreadLocal myThreadLocal) { staff1 = staff; this.myThreadLocal = myThreadLocal; System.out.println("con staff" + staff); } public void run() { myThreadLocal.set(staff1); while (true) { StaffInfoVO staff = (StaffInfoVO) myThreadLocal.get(); // System.out.println("staff:" + staff); int i = staff.getCount().intValue(); System.out.println("Thread name:" + Thread.currentThread().getName() + " staff count:" + i); staff.setCount(new Integer(i + 1)); try { Thread.currentThread().sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } public class StaffInfoVO implements Serializable { /** * */ private static final long serialVersionUID = -57676961756664705L; private String name; private String staffNo; private List roles; private Integer count; // 如果不使用synchronized,大家一眼就看到区别了. public synchronized Integer getCount() { return count; } // 如果不使用synchronized,大家一眼就看到区别了. public synchronized void setCount(Integer count) { this.count = count; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List getRoles() { return roles; } public void setRoles(List roles) { this.roles = roles; } public String getStaffNo() { return staffNo; } public void setStaffNo(String staffNo) { this.staffNo = staffNo; } } 首先产生一个引用对象staff1 . 然后产生10个MyThread 类型的线程对象. 这10个线程中每一个都持有私有的ThreadLocal对象. 在这10个线程开始start的时候,在run方法中将staff1对象设置到各自私有的ThreadLocal对象中. 当我们注释掉staff1中的synchronized时候,我们马上就看到出现了count数据的不一致. 只有当我们使用synchronized,不一致的情况解决了. 当StaffInfoVO的count的set/get方法不是synchronized的时候,虽然每个Thread维护了一个对应的ThreadLocal,而ThreadLocal只是对于Thread对象中的ThreadLocalMap的接口暴露(get/set添加和取得保存的对象)对于被保存的对象,只是保存了引用的情况下,并且被保存对象的状态改变的方法不是synchronized的时候,并不能保证同步. 这个是ThreadLocal的局限性.并没有synchronized关键字那么安全.在我看来ThreadLocal MS不是用来处理同步,而只是为了保存当前线程自有的某个状态.当ThreadLocal.set(Object obj)方法时,取得Thread.currentThread.ThreadLocalMap对象,然后将自己作为KEY保存到ThreadLocalMap中.ThreadLocal.get处理方法类似. 所以最后我得出的结论就是:synchronized是用来处理多线程环境下的数据同步,而ThreadLocal只是为了保存当前线程私有的某种状态. 以上内容,如有不当,请指出. 谢谢. 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-05-25
ThreadLocal理解成CurrentThreadContext就行了.
|
|
返回顶楼 | |
发表时间:2007-05-25
shaucle 写道 ThreadLocal理解成CurrentThreadContext就行了. 也对!其实我们光看这个类的名字就知道了.ThreadLocal!
非常言简意赅.也许叫ThreadLocalDataHolder更好.^_^ |
|
返回顶楼 | |
发表时间:2007-05-25
越来越离谱了,每个线程 new ThreadLocal。。。
|
|
返回顶楼 | |
发表时间:2007-05-25
很多framework都用到了ThreadLocal:
spring,acegi,seam等 不是说ThreadLocal不重要,只是认为这些东东比较基本 就像Proxy和NIO等,很多应用(包括框架)都是基于此的. |
|
返回顶楼 | |
发表时间:2007-05-25
从这个角度上来解释ThreadLocal,虽然技术上没什么,但是很容易让人误解。
首先要能清楚为什么要使用ThreadLocal,如果没有ThreadLocal,能不能解决问题。 没有ThreadLocal的话,每个Thread中都有输入自己的一个本地变量,但是在整个Thread的生命中,如果要穿梭很多class的很多method来使用这个本地变量的话,就要一直一直向下传送这个变量,显然很麻烦。 那么怎么才能在这个Thread的生命中,在任何地方都能够方便的访问到这个变量呢,这时候ThreadLocal就诞生了。 ThreadLocal就是这么个作用,除此之外和通常使用的本地变量没有任何区别。 我奇怪的是为什么非要和synchronized扯上关系,完全风马牛不相及的两个东西。 |
|
返回顶楼 | |
发表时间:2007-05-25
"我奇怪的是为什么非要和synchronized扯上关系,完全风马牛不相及的两个东西。"
对啊,虽然内容没错,但却有点扯... |
|
返回顶楼 | |
发表时间:2007-05-25
MyThreadLocal{
Map map = new HashMap(); get(){ return map.get(Thread.currentThread()); } set(Object o){ map.put(Thread.currentThread(), o); } } |
|
返回顶楼 | |
发表时间:2007-05-25
本来就是基础的东西,本不想拿出来说的.
动机只是想说清楚. 呵呵~~不扯了. 结贴. |
|
返回顶楼 | |
发表时间:2007-05-25
俺以前一个项目在没有ThreadLocal时的实现...
|
|
返回顶楼 | |