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、分布式缓存、数据结构等等。