Java中的ThreadLocal类容许咱们建立只能被同一个线程读写的变量。所以,若是一段代码含有一个ThreadLocal变量的引用,即便两个线程同时执行这段代码,它们也没法访问到对方的ThreadLocal变量。java
如下代码展现了如何建立一个ThreadLocal变量:面试
private ThreadLocal myThreadLocal = new ThreadLocal();
咱们能够看到,经过这段代码实例化了一个ThreadLocal对象。咱们只须要实例化对象一次,而且也不须要知道它是被哪一个线程实例化。虽然全部的线程都能访问到这个ThreadLocal实例,可是每一个线程却只能访问到本身经过调用ThreadLocal的set()方法设置的值。即便是两个不一样的线程在同一个ThreadLocal对象上设置了不一样的值,他们仍然没法访问到对方的值。算法
一旦建立了一个ThreadLocal变量,你能够经过以下代码设置某个须要保存的值:spring
myThreadLocal.set("A thread local value”);
能够经过下面方法读取保存在ThreadLocal变量中的值:数据库
String threadLocalValue = (String) myThreadLocal.get();
get()方法返回一个Object对象,set()对象须要传入一个Object类型的参数。设计模式
咱们能够建立一个指定泛型类型的ThreadLocal对象,这样咱们就不须要每次对使用get()方法返回的值做强制类型转换了。下面展现了指定泛型类型的ThreadLocal例子:缓存
private ThreadLocal myThreadLocal = new ThreadLocal<String>();
如今咱们只能往ThreadLocal对象中存入String类型的值了。数据结构
而且咱们从ThreadLocal中获取值的时候也不须要强制类型转换了。多线程
因为在ThreadLocal对象中设置的值只能被设置这个值的线程访问到,线程没法在ThreadLocal对象上使用set()方法保存一个初始值,而且这个初始值能被全部线程访问到。并发
可是咱们能够经过建立一个ThreadLocal的子类而且重写initialValue()方法,来为一个ThreadLocal对象指定一个初始值。就像下面代码展现的那样:
private ThreadLocal myThreadLocal = new ThreadLocal<String>() { @Override protected String initialValue() { return "This is the initial value"; } };
下面是一个完整的可执行的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类是ThreadLocal类的子类。ThreadLocal中每一个线程拥有它本身的值,与ThreadLocal不一样的是,InheritableThreadLocal容许一个线程以及该线程建立的全部子线程均可以访问它保存的值。
私信回复 资料 领取一线大厂Java面试题总结+阿里巴巴泰山手册+各知识点学习思惟导+一份300页pdf文档的Java核心知识点总结!
这些资料的内容都是面试时面试官必问的知识点,篇章包括了不少知识点,其中包括了有基础知识、Java集合、JVM、多线程并发、spring原理、微服务、Netty 与RPC 、Kafka、日记、设计模式、Java算法、数据库、Zookeeper、分布式缓存、数据结构等等。