ThreadLocal与线程本地变量

5

ThreadLocal.get/put有什么不同之处?

class ThreadT extends Thread {
private SomeObj obj;
.....
}

我认为,如果我错了请纠正我,这个对象对于每个线程也是不同的。即,如果我们有5个ThreadT对象,那么每个线程都会有5个不同的obj对象。

那么,既然如此,为什么我们需要使用ThreadLocal呢?

如果我对其中任何一个理解不正确,请纠正我。


可能是 http://stackoverflow.com/questions/10235253/in-java-if-i-call-a-class-that-extends-thread-from-another-runnable-object-whi 的重复问题。 - Linga
请查看Java Thread Local - 如何使用和代码示例。特别是关于“什么是Thread Local?”的部分。 - Charlee Chitsuk
1
简单来说,ThreadLocal 不必与线程关联,它可以与任何对象或结构相关联。 - Patashu
3个回答

6

从文档中可以得知,这个类提供了线程本地变量。这些变量与普通变量不同之处在于,每个访问它的线程(通过其 get 或 set 方法)都有自己独立初始化的变量副本。

如果您编写的类直接扩展线程,则您的方法将起作用。但是对于需要 ThreadLocal 变量但没有直接访问其 Thread 实例的类呢?

在这种情况下,ThreadLocal 就很有用了。特别是在服务器环境中,大部分时间不直接使用线程的情况下。


谢谢,我也在想同样的事情,但是没有正确地联系起来。现在能够考虑它的用途了。谢谢。 - Amit

4
您的类继承Thread并不会使其字段特殊。假设您的类有get / set方法。
    final ThreadT tt = new ThreadT();

    new Thread() {
        public void run() {
            tt.set(new Object());
        };
    }.start();

    new Thread() {
        public void run() {
            Object obj = tt.get();
        };
    }.start();

第二个线程将得到第一个线程放置的对象。这种情况在ThreadLocal中不会发生。

0

我已经写了程序

class ThreadRun implements Runnable {

    NumberValue number;
    int value;

    ThreadRun(NumberValue number,int value) {


        this.number=number;
        this.value = value;
        Thread t = new Thread(this);
        t.start();
    }

    @Override
    public void run() {

        number = number.getThreadLocal();


        number.setId(number.getId()+value);

        System.out.println(number.getId());

    }

}

public class ThreadTest {
    public static void main(String[] args) {
        NumberValue number = new NumberValue(1);


        new ThreadRun(number, 1);
        new ThreadRun(number, 2);
    }
}

class NumberValue {

    int id;



    ThreadLocal<NumberValue> threadLocal = new ThreadLocal<NumberValue>() {

    @Override
    protected NumberValue initialValue() {

        return new NumberValue(id);
    }
    };



    NumberValue(int id) {
        this.id = id;

    }



    /**
     * @return the id
     */
    public int getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(int id) {
        this.id = id;
    }
    public NumberValue getThreadLocal() {
        return threadLocal.get();
    }






}

输出: 2 3 这个输出是我们期望的输出

但是当你注释掉

// number = number.getThreadLocal(); 并运行程序,输出将会是 输出: 3 4 所以当注释掉 // number = number.getThreadLocal(); 时,数据就被破坏了。因此,ThreadLocal会创建 NumberValue 的本地副本。但是当不使用ThreadLocal时,同一个对象实例在线程之间共享,因此数据结果会比实际结果更加错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接