ThreadLocal
是提供线程局部变量的类,用于实现线程安全。 存储的数据只能由特定线程访问。
ThreadLocal
扩展了Object
类,并提供了线程限制,它是局部变量的“一部分”。
创建ThreadLocal
变量
ThreadLocal threadLocalExample = new ThreadLocal();
上面代码中ThreadLocal
对象的实例化仅需要针对每个线程进行。
就像大多数类一样,一旦有了ThreadLocal
的实例,就可以在其上调用方法。 一些方法是:
get()
:返回此线程局部变量的当前线程副本中的值initialValue()
:返回当前线程局部变量的当前线程初始值remove()
:从当前线程中删除当前线程局部变量的值set(T value)
:将当前线程局部变量的当前线程副本设置为指定值
有关这些方法的更多详细信息,请访问原始 Oracle 文档。
ThreadLocal
实例是希望将状态与线程相关联的类中的私有静态字段(在大多数情况下)
实现示例
public class ThreadLocalExample {
public static class Example implements Runnable {
private ThreadLocal<String> example = new ThreadLocal<String>();
// override the run() method that comes from implementing Runnable class
@Override
public void run() {
try {
System.out.println("Getting values...");
Thread.sleep(2000);
}
catch (InterruptedException e) {
System.out.println(e);
}
example.set("Just a random text that will be displayed before the remove function");
System.out.println("Before remove: " + example.get());
example.remove();
System.out.println("After remove: " + example.get());
}
}
public static void main(String[] args) {
/* EXAMPLE THAT DOES NOT HAVE TO DO ANYTHING WITH THE STATIC CLASS ABOVE main*/
ThreadLocal<String> local = new ThreadLocal<String>();
local.set("First");
System.out.println("Value: " + local.get());
local.set("Second");
System.out.println("Value: " + local.get());
local.remove();
System.out.println("Value: " + local.get());
/* NEW EXAMPLE THAT USES THE STATIC CLASS DECLARED ABOVE main */
Example runnable = new Example();
Thread thread = new Thread(runnable);
thread.start();
}
}
输出
Value: First
Value: Second
Value: null
Getting values...
Before remove: Just a random text that will be displayed before the remove function
After remove: null
分解
上面的代码显示了两种使它起作用的方法:一种是通过拥有Runnable
对象并将其传递给Thread
实例,然后覆盖run()
方法,或者您可以简单地创建一个ThreadLocal
实例并为其设置值,然后 可以获取或删除它。 从上面的示例中可以看到,即使它是相同的变量(局部变量),也可以包含不同的值。 在第一种情况下,它包含值"First"
。 在第二种情况下,它包含值"Second"
。 对于其他实现,我只显示了一个线程。 但是,每个线程都是独立的–意味着,如果您要创建另一个Thread
实例(例如thread2
),并对其进行start()
,它将独立运行,并且与其他Thread
实例变量无关。 要进行检查,可以在静态类中创建一个ThreadLocal
实例,然后在重写的run()
方法中创建一个随机数,然后使用set()
方法将其传递给当前线程。 您将看到,如果您在两个或多个不同的线程上调用它,则它们都将具有不同的值。