2010-10-18 47 views
8

Java中ThreadLocal的典型用法是什么?什么时候用它?我无法申请这篇java docs文章的详细信息。ThreadLocal的使用

+2

可能重复[何时以及如何我应该使用一个ThreadLocal变量?](http://stackoverflow.com/questions/817856/when-and-how-should-i-use-a-threadlocal-变量) – YoK 2010-10-18 07:12:36

回答

4

适用于您希望使用非线程安全但不想同步对它们的访问(出于性能原因)的对象。 或多或少,您为需要多次使用的对象创建一个访问器,以确保每个可能调用该访问器的线程都获得一个不同的未使用的对象。 一个非常典型的用法是使用SimpleDateFormat,它是一个类,如果它是线程安全的,那么您的实例将被声明为静态的,以便重用相同的实例。

下面是描述它的好文章:Dr. Dobbs: Using Thread-Local Variables In Java

4

也许更能说明问题的例子可以给你很好:

method1(): ... method2(somedata) ... 
method2(somedata): ... method3(somedata) ... 
method3(somedata): ... method4(somedata) ... 
method4(somedata): ... do something with somedata ... 

这种情况发生,例如在多层架构(UI调用远程门面,远程外观调用应用程序层,应用程序层调用域图层,域图层调用持久层,...)如果这些方法()属于不同的类,那么除了为我们的大多数方法添加额外参数“somedata”之外,没有好方法来传递这些数据代码,这打破了例如开闭原则。这个问题的解决方法是ThreadLocal的:

method1(): ... threadLocal.set(somedata); method2(); threadLocal.set(null); ... 
method2(): ... method3() ... 
method3(): ... method4() ... 
method4(): ... do something with threadLocal.get() ... 
5

我会说,最典型的ThreadLocal的使用是当你有一些对象,有一个流程中可以访问无处不在,你不想通过参照本覆盖所有图层的对象。像单例模式,但每个线程。

这些示例是数据库连接,hibernate会话等。您可以在流程开始的某个位置打开它们,在流程结束时提交/关闭并在流程中随处使用。

0

如果您的流程与线程绑定在一起,如AlexR所述,您可以使用private static final ThreadLocal<T> p属性创建public final class C,添加存取方法。然后你可以在你的流程中分别使用p.set(),p.remove()和p.get()。的

public final class C { 
    private static final ThreadLocal<String> p = new ThreadLocal<String>(); 

    // initialize property at the begining of your thread (flow) 
    public static void set(final String s){ 
     p.set(s); 
    } 

    // use property during the thread's lifecycle 
    // for instance: C.get().equals(myString) 
    public static String get(){ 
     return p.get(); 
    } 

    // remember to remove property from the thread when you're done, specially if it came from a thread pool 
    public static void remove(){ 
     p.remove(); 
    } 
}