Java 中的 ThreadLocal 类容许咱们创立只能被同一个线程读写的变量。因而,如果一段代码含有一个 ThreadLocal 变量的援用,即便两个线程同时执行这段代码,它们也无法访问到对方的 ThreadLocal 变量。
如何创立 ThreadLocal 变量
以下代码展现了如何创立一个 ThreadLocal 变量:
private ThreadLocal myThreadLocal = new ThreadLocal();
咱们能够看到,通过这段代码实例化了一个 ThreadLocal 对象。咱们只须要实例化对象一次,并且也不须要晓得它是被哪个线程实例化。尽管所有的线程都能拜访到这个 ThreadLocal 实例,然而每个线程却只能拜访到本人通过调用 ThreadLocal 的 set()办法设置的值。即便是两个不同的线程在同一个 ThreadLocal 对象上设置了不同的值,他们依然无法访问到对方的值。
如何拜访 ThreadLocal 变量
一旦创立了一个 ThreadLocal 变量,你能够通过如下代码设置某个须要保留的值:
myThreadLocal.set("A thread local value”);
能够通过上面办法读取保留在 ThreadLocal 变量中的值:
String threadLocalValue = (String) myThreadLocal.get();
get()办法返回一个 Object 对象,set()对象须要传入一个 Object 类型的参数。
为 ThreadLocal 指定泛型类型
咱们能够创立一个指定泛型类型的 ThreadLocal 对象,这样咱们就不须要每次对应用 get()办法返回的值作强制类型转换了。上面展现了指定泛型类型的 ThreadLocal 例子:
private ThreadLocal myThreadLocal = new ThreadLocal<String>();
当初咱们只能往 ThreadLocal 对象中存入 String 类型的值了。
并且咱们从 ThreadLocal 中获取值的时候也不须要强制类型转换了。
如何初始化 ThreadLocal 变量的值
因为在 ThreadLocal 对象中设置的值只能被设置这个值的线程拜访到,线程无奈在 ThreadLocal 对象上应用 set()办法保留一个初始值,并且这个初始值能被所有线程拜访到。
然而咱们能够通过创立一个 ThreadLocal 的子类并且重写 initialValue()办法,来为一个 ThreadLocal 对象指定一个初始值。就像上面代码展现的那样:
private ThreadLocal myThreadLocal = new ThreadLocal<String>() {
@Override
protected String initialValue() {return "This is the initial value";}
};
一个残缺的 ThreadLocal 例子
上面是一个残缺的可执行的 ThreadLocal 例子:
public class ThreadLocalExample {
public static class MyRunnable implements Runnable {private ThreadLocal threadLocal = new ThreadLocal();
@Override
public void run() {threadLocal.set((int) (Math.random() * 100D));
try {Thread.sleep(2000);
} catch (InterruptedException e) { }
System.out.println(threadLocal.get());
}
}
public static void main(String[] args) {MyRunnable sharedRunnableInstance = new MyRunnable();
Thread thread1 = new Thread(sharedRunnableInstance);
Thread thread2 = new Thread(sharedRunnableInstance);
thread1.start();
thread2.start();}
}
下面的例子创立了一个 MyRunnable 实例,并将该实例作为参数传递给两个线程。两个线程别离执行 run()办法,并且都在 ThreadLocal 实例上保留了不同的值。如果它们拜访的不是 ThreadLocal 对象并且调用的 set()办法被同步了,则第二个线程会笼罩掉第一个线程设置的值。然而,因为它们拜访的是一个 ThreadLocal 对象,因而这两个线程都无奈看到对方保留的值。也就是说,它们存取的是两个不同的值。
对于 InheritableThreadLocal
InheritableThreadLocal 类是 ThreadLocal 类的子类。ThreadLocal 中每个线程领有它本人的值,与 ThreadLocal 不同的是,InheritableThreadLocal 容许一个线程以及该线程创立的所有子线程都能够拜访它保留的值。
最初
私信回复 材料 支付一线大厂 Java 面试题总结 + 阿里巴巴泰山手册 + 各知识点学习思维导 + 一份 300 页 pdf 文档的 Java 外围知识点总结!
这些材料的内容都是面试时面试官必问的知识点,篇章包含了很多知识点,其中包含了有基础知识、Java 汇合、JVM、多线程并发、spring 原理、微服务、Netty 与 RPC、Kafka、日记、设计模式、Java 算法、数据库、Zookeeper、分布式缓存、数据结构等等。