Java ThreadLocal is used to create thread local variables. We know that all threads of an Object share it’s variables, so the variable is not thread safe. We can use synchronization for thread safety but if we want to avoid synchronization, we can use ThreadLocal
variables.
Java ThreadLocal用于创建线程局部变量。 我们知道对象的所有线程都共享它的变量,因此该变量不是线程安全的。 我们可以使用同步来确保线程安全,但是如果要避免同步,可以使用ThreadLocal
变量。
Java ThreadLocal (Java ThreadLocal)
Every thread has it’s own ThreadLocal
variable and they can use it’s get() and set() methods to get the default value or change it’s value local to Thread.
每个线程都有自己的ThreadLocal
变量,他们可以使用它的get()和set()方法获取默认值或将其值更改为Thread本地。
ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread.
ThreadLocal实例通常是希望将状态与线程关联的类中的私有静态字段。
Java ThreadLocal示例 (Java ThreadLocal Example)
Here is a small example showing use of ThreadLocal in java program and proving that every thread has it’s own copy of ThreadLocal variable.
这是一个小示例,显示了在Java程序中使用ThreadLocal并证明每个线程都有其自己的ThreadLocal变量副本。
ThreadLocalExample.java
ThreadLocalExample.java
package com.journaldev.threads;
import java.text.SimpleDateFormat;
import java.util.Random;
public class ThreadLocalExample implements Runnable{
// SimpleDateFormat is not thread-safe, so give one to each thread
private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
@Override
protected SimpleDateFormat initialValue()
{
return new SimpleDateFormat("yyyyMMdd HHmm");
}
};
public static void main(String[] args) throws InterruptedException {
ThreadLocalExample obj = new ThreadLocalExample();
for(int i=0 ; i<10; i++){
Thread t = new Thread(obj, ""+i);
Thread.sleep(new Random().nextInt(1000));
t.start();
}
}
@Override
public void run() {
System.out.println("Thread Name= "+Thread.currentThread().getName()+" default Formatter = "+formatter.get().toPattern());
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
//formatter pattern is changed here by thread, but it won't reflect to other threads
formatter.set(new SimpleDateFormat());
System.out.println("Thread Name= "+Thread.currentThread().getName()+" formatter = "+formatter.get().toPattern());
}
}
Output of the above java ThreadLocal example program is:
上面的java ThreadLocal示例程序的输出是:
Thread Name= 0 default Formatter = yyyyMMdd HHmm
Thread Name= 1 default Formatter = yyyyMMdd HHmm
Thread Name= 0 formatter = M/d/yy h:mm a
Thread Name= 2 default Formatter = yyyyMMdd HHmm
Thread Name= 1 formatter = M/d/yy h:mm a
Thread Name= 3 default Formatter = yyyyMMdd HHmm
Thread Name= 4 default Formatter = yyyyMMdd HHmm
Thread Name= 4 formatter = M/d/yy h:mm a
Thread Name= 5 default Formatter = yyyyMMdd HHmm
Thread Name= 2 formatter = M/d/yy h:mm a
Thread Name= 3 formatter = M/d/yy h:mm a
Thread Name= 6 default Formatter = yyyyMMdd HHmm
Thread Name= 5 formatter = M/d/yy h:mm a
Thread Name= 6 formatter = M/d/yy h:mm a
Thread Name= 7 default Formatter = yyyyMMdd HHmm
Thread Name= 8 default Formatter = yyyyMMdd HHmm
Thread Name= 8 formatter = M/d/yy h:mm a
Thread Name= 7 formatter = M/d/yy h:mm a
Thread Name= 9 default Formatter = yyyyMMdd HHmm
Thread Name= 9 formatter = M/d/yy h:mm a
As you can see from the output that Thread-0 has changed the value of formatter but still thread-2 default formatter is same as the initialized value. You can see the same pattern for other threads too.
从输出中可以看到,Thread-0更改了格式化程序的值,但线程2默认格式化程序仍与初始化值相同。 您也可以在其他线程中看到相同的模式。
Update: ThreadLocal class is extend in Java 8 with a new method withInitial()
that takes Supplier functional interface as argument. So we can use lambda expressions to easily create the ThreadLocal instance. For example, above formatter ThreadLocal variable can be defined in one line as below:
更新 :ThreadLocal类在Java 8中通过带有withInitial()
的新方法进行了扩展,该方法以Supplier功能接口作为参数。 因此,我们可以使用lambda表达式轻松创建ThreadLocal实例。 例如,可以在以下一行中定义上述格式化程序ThreadLocal变量:
private static final ThreadLocal<SimpleDateFormat> formatter =
ThreadLocal.<SimpleDateFormat>withInitial
(() -> {return new SimpleDateFormat("yyyyMMdd HHmm");});
If you are new to Java 8 features, please check out Java 8 Features and Java 8 Functional Interfaces.
如果您不熟悉Java 8功能,请查看Java 8功能和Java 8功能接口 。
That’s all for ThreadLocal in java programming.
这就是Java编程中ThreadLocal的全部内容。
Reference: API Doc
参考: API文档
翻译自: https://www.journaldev.com/1076/java-threadlocal-example