Java ThreadLocal示例

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值