当前位置: 首页 > 编程笔记 >

Java ThreadLocal的设计理念与作用

潘阳舒
2023-03-14
本文向大家介绍Java ThreadLocal的设计理念与作用,包括了Java ThreadLocal的设计理念与作用的使用技巧和注意事项,需要的朋友参考一下

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 ThreadLocal的设计理念与作用详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对小牛知识库网站的支持!

 类似资料:
  • Angel的设计理念 Angel的整体设计理念,是简约而不简单,做一个灵活而强大的参数服务器,并在此之上,提供多种机器学习算法,和PS服务,扩展为一个分布式机器学习平台。 因此,在开发之时,Angel从如下5个方向,对整体进行了改进和设计,并在它们之间进行了平衡。包括: 易用性 灵活性 性能 可扩展性 稳定性 另外,Angel设计之初,并没有特地为深度学习量身定做,但随着深度学习日趋流行,而PS模

  • 这一章将介绍 Kubernetes 的设计理念及基本概念。 Kubernetes设计理念与分布式系统 分析和理解Kubernetes的设计理念可以使我们更深入地了解Kubernetes系统,更好地利用它管理分布式部署的云原生应用,另一方面也可以让我们借鉴其在分布式系统设计方面的经验。 分层架构 Kubernetes设计理念和功能其实就是一个类似Linux的分层架构,如下图所示 核心层:Kubern

  • 导航栏 uniapp可以通过配置pages.json生成原生元素的导航栏,简要说明如下: 优点是可以快速渲染,配置便捷,还可以带入一部分原生内容(针对App Store) 缺点是配置不够灵活,遮罩无法覆盖导航栏等 建议: 如果开发者使用nuve,可以直接自定义导航栏,无需使用uniapp自带的 如果是普通的vue页面,直接使用uniapp自带导航栏。如果自带的不能满足,条件允许就用subNVue绘

  • 阐述open-falcon设计过程中的各种思考

  • 阐述open-falcon设计过程中的各种思考

  • TeaScript 的适用场景和人群 某天,我收到一个需求,要把100个flv视频转为swf格式。但我发现,没有一个语言能很快地完成这个任务。因为它需要用到flv和swf解析的第三方库。而目前的语言使用第三方库则都是一个头疼的问题,特别是改别人的代码。 于是,我就在想能不能设计一个语言,让使开源代码的成本降到最低。 设计目标 TeaScript 设计的目标是能快速用上别人的代码。 一些高级语言都提