ThreadLocal的使用

时间:2010-10-18 07:01:43

标签: java

在java中,ThreadLocal的典型用法是什么?什么时候使用它?我无法通过此java docs文章提供申请详情。

4 个答案:

答案 0 :(得分:5)

我想说最典型的ThreadLocal用法是当你有一个对象必须在一个流程中随处可访问而你不想在所有层上传递对该对象的引用。像单身模式,但每个线程。

示例是数据库连接,休眠会话等。您可以在流程的开头某处打开它们,在流程结束时提交/关闭,并在流程中随处使用。

答案 1 :(得分:4)

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

这是一篇描述它的好文章:Dr. Dobbs: Using Thread-Local Variables In Java

答案 2 :(得分: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() ...

答案 3 :(得分:0)

如果您的流程与某个线程相关联,例如AlexR提及,您可以创建一个public final class C属性private static final ThreadLocal<T> p,添加访问器方法。然后你可以在你的流程中分别使用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();
    }
}