关于java:Java-ThreadLocal的使用

37次阅读

共计 2280 个字符,预计需要花费 6 分钟才能阅读完成。

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

正文完
 0