2012-04-27 79 views
3

根据ThreadLocal的javadoc,这听起来像是它针对1+个原子字段的线程专用容器。使用ThreadLocal vs Atomic

ThreadLocal目的代表所有单个Thread原子领域,或者是只提供了一个方便的容器,当你有多个实例Atomic*需要进行逻辑分组在一起吗?

我想我想知道为什么我会想要使用ThreadLocal而不是比如说AtomicLongAtomicInteger?提前致谢!

回答

8

ThreadLocal的目的是,而不是的字段必须是原子的 - 不需要将它们的值与集中式存储器同步。它们是线程本地的,只存在于线程本地存储器中。

为什么我要使用ThreadLocal而不是AtomicLong或AtomicInteger?

ThreadLocal对于存储每个线程副本的东西非常有用。例如一个SimpleDateFormat这是不幸的不可重入。

private final ThreadLocal<DateFormat> threadLocal = 
     new ThreadLocal<DateFormat>() { 
    @Override 
    protected DateFormat initialValue() { 
     return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS"); 
    } 
}; 
... 
// get one that is per-thread 
DateFormat dateFormat = threadLocal.get(); 

这是一个有用的模式,因为这时我们不必synchronize就可以了,也不用担心有记忆力障碍有任何volatile或其他原子操作。

+0

Thanks @Gray!所以,如果我的类不是不可变的,而且我需要在它们的实例上同步,但不想进入所有的java.util.concurrent。*“stuff”,我可以用'ThreadLocal '......这是一个公平的总结?!? – IAmYourFaja 2012-04-27 20:28:45

+0

是的@herpylderp(优秀的用户名btw),只要他们只能在本地线程。线程完成后,其所有'ThreadLocal'类都可以GC'd。不可变的和不可重入的类也是如此 - 虽然可能非租用者在定义上不是不可变的。 – Gray 2012-04-27 20:32:03

1

我想我不知道为什么我会永远想使用一个ThreadLocal的,而不是,比方说,一个AtomicLong的或的AtomicInteger?

他们服务完全不同的目的。 ThreadLocal意味着您不必担心通过授予每个线程自己的对象副本来进行同步。因此,存储在ThreadLocal中的对象不可能被多个线程访问。

Atomic*也意味着您不必担心同步,但它们专门用于跨线程共享。

+0

如果您在别处发布其引用,您可以*从其他线程访问存储在“ThreadLocal”中的对象。更重要的是,'AtomicReference'不会消除它引用的对象的同步需求。它只提供线程之间引用的安全发布。将'ArrayList'粘贴到'AtomicReference'中不会使'ArrayList'本身是线程安全的。 – 2012-04-27 21:16:16