多线程面试题_Java中的线程本地存储-程序员宅基地

技术标签: spring  c++  python  java  多线程  

多线程面试题

多线程面试题

线
开发人员中鲜为人知的功能之一是线程本地存储。 这个想法很简单,需要它的场景是……我们需要的数据在线程中很好。 如果我们有两个线程,则它们引用相同的全局变量,但我们希望它们具有彼此独立初始化的单独值。

大多数主要的编程语言都有该概念的实现。 例如,C ++ 11甚至具有thread_local关键字,Ruby选择了一种API方法

从版本1.2开始,Java还使用java.lang.ThreadLocal <T>及其子类java.lang.InheritableThreadLocal <T>来实现该概念,因此这里没有什么新鲜的东西。

假设由于某种原因,我们需要为线程创建一个Long特定对象。 使用线程本地将很简单:

public class ThreadLocalExample {

  public static class SomethingToRun implements Runnable {

    private ThreadLocal threadLocal = new ThreadLocal();

    @Override
    public void run() {
      System.out.println(Thread.currentThread().getName() + " " + threadLocal.get());

      try {
        Thread.sleep(2000);
      } catch (InterruptedException e) {
      }

      threadLocal.set(System.nanoTime());
      System.out.println(Thread.currentThread().getName() + " " + threadLocal.get());
    }
  }


  public static void main(String[] args) {
    SomethingToRun sharedRunnableInstance = new SomethingToRun();

    Thread thread1 = new Thread(sharedRunnableInstance);
    Thread thread2 = new Thread(sharedRunnableInstance);

    thread1.start();
    thread2.start();
  }

}

以下代码的一个可能示例运行将导致:

Thread-0 null

Thread-0 132466384576241

Thread-1 null

Thread-1 132466394296347

在开始时,两个线程的值都设置为null,显然每个线程都使用单独的值,因为在将Thread-0的值设置为System.nanoTime()之后,它将不会对Thread-1的值产生任何影响如我们所愿,一个线程作用域的long变量。

一个不错的副作用是线程从各种类调用多个方法的情况。 他们都将能够使用相同的线程范围变量,而无需进行重大的API更改。 由于未明确传递价值,因此可能难以测试且不利于设计,但这完全是一个单独的主题。

在哪些地区流行使用线程局部语言的框架?

作为Java中最受欢迎的框架之一,Spring在内部将ThreadLocals用于许多部分,可以通过简单的github 搜索轻松地看到。 大多数用法与当前用户的操作或信息有关。 实际上,这实际上是JavaEE世界中ThreadLocals的主要用途之一,例如在RequestContextHolder中存储当前请求的信息:

private static final ThreadLocal<RequestAttributes> requestAttributesHolder = 
    new NamedThreadLocal<RequestAttributes>("Request attributes");

UserCredentialsDataSourceAdapter中的当前JDBC连接用户凭据。

如果我们回到RequestContextHolder,则可以使用此类访问代码中任何位置的所有当前请求信息。

常见的用例是LocaleContextHolder ,它可以帮助我们存储当前用户的语言环境。

Mockito使用它来存储当前的“全局” 配置,如果我们看看那里的任何框架,那么也很有可能找到它。

线程本机和内存泄漏

我们了解了这个很棒的小功能,所以让我们在各处使用它。 我们可以做到这一点,但很少有Google搜索,而且我们发现那里的大多数人都说ThreadLocal是邪恶的。 并非完全正确,它是一个不错的实用程序,但在某些情况下,可能容易造成内存泄漏。

“您是否可以通过线程局部变量导致意外的对象保留? 你当然可以。 但是您也可以使用数组来执行此操作。 这并不意味着线程局部变量(或数组)是坏事。 只是您必须谨慎使用它们。 使用线程池需要格外小心。 随意使用线程池与随意使用线程本地变量相结合会导致意外的对象保留,这在许多地方都已提到。 但是,将责任归咎于线程本机是没有根据的。” –约书亚·布洛赫(Joshua Bloch)

如果ThreadLocal在应用程序服务器上运行,则很容易使用ThreadLocal在服务器代码中创建内存泄漏。 ThreadLocal上下文与运行它的线程相关联,一旦线程死掉,它将被丢弃。 现代的应用服务器使用线程池,而不是在每个请求上创建新线程,这意味着您最终可能会在应用程序中无限期地容纳大型对象。 由于线程池来自应用服务器,因此即使卸载应用程序,我们的内存泄漏也可能继续存在。 修复方法很简单,可以释放不需要的资源。

另一个ThreadLocal滥用是API设计。 我经常看到到处都在使用RequestContextHolder (它持有ThreadLocal ),例如DAO层。 后来,如果有人在诸如和调度程序之类的请求之外调用相同的DAO方法,他将得到一个非常糟糕的惊喜。

这产生了不可思议的魔力和许多维护开发人员,他们最终将弄清楚您的住所并进行访问。 即使ThreadLocal中的变量是线程本地的,它们在代码中还是非常全局的。 在使用它之前,请确保您确实需要此线程作用域。

有关该主题的更多信息

翻译自: https://www.javacodegeeks.com/2014/12/thread-local-storage-in-java.html

多线程面试题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/cunfen9460/article/details/112551718

智能推荐

Linux阻塞与非阻塞_linux阻塞是什么-程序员宅基地

文章浏览阅读2.9k次,点赞3次,收藏14次。1.阻塞(block)概念:指进程或线程在执行设备操作或管道,或则网络时,不能获取到资源就被挂起,直到满足可操作的条件后在进行操作,被挂起的进程进入休眠状态,从运行队列移走,直到等待的条件满足才继续执行。也就是执行到某些函数时必须等待某个事件发生函数才返回。2.非阻塞(non_block):进程就算没有获取到资源或没有等到事件发生时不挂起,通常会直接放弃或不断查询,直到可以进行的位置。也就..._linux阻塞是什么

java反射机制初步认识<一>获取成员变量_java 如何给实体的long类型字段反射赋值-程序员宅基地

文章浏览阅读1.1k次。作为一个Java新人,我谈谈自己对Java反射机制的认识:_java 如何给实体的long类型字段反射赋值

ubuntu下gedit设置行号、tab宽度、显示样式等图文详细设置_gedit行号-程序员宅基地

文章浏览阅读6.2k次,点赞8次,收藏16次。1 gedit简介 gedit是一个GNOME桌面环境下兼容UTF-8的文本编辑器。它使用GTK+编写而成,因此它十分的简单易用,有良好的语法高亮,对中文支持很好,支持包括gb2312、gbk在内的多种字符编码。gedit是一个自由软件,它是Linux 下的一个纯文本编辑器,但你也可以把它用来当成是一个集成开发环境 (IDE), 它会根据不同的语言高亮显现关键字和标识符。 gedit语法高亮和编辑多个文件的功能,同时利用GNOME VFS库,它还可以编辑远程文件。它支持完..._gedit行号

达梦数据库查看(解析)归档日志_达梦数据库日志查看-程序员宅基地

文章浏览阅读5.9k次,点赞5次,收藏11次。达梦数据库解析归档日志,达梦开启归档_达梦数据库日志查看

DVWA中的SQL injection_dvwasqliniection的首界面找到右下角“view source”按钮并点击-程序员宅基地

文章浏览阅读121次。这个题难搞啊,还是low里面的,废了废了,话不多说,经参考,上思路一.先来了解知识点1.在MySQL中,把 information_schema 看作是一个数据库,确切说是信息数据库。2.information_schema数据库表说明:SCHEMATA表:提供了当前mysql实例中所有数据库的信息。是show databases的结果取之此表。TABLES表:提供了关于数据库中的表的信..._dvwasqliniection的首界面找到右下角“view source”按钮并点击

mvc分层架构与JavaEE分层架构_java ee分层和mvc-程序员宅基地

文章浏览阅读248次。mvc分层架构与JavaEE分层架构mvcJavaEE架构mvc简介:model,view,controllr三层架构model:数据模型,每一个类就是一个模型,每一个类对象代表一个完整的数据view: 视图,如jsp/htmlcontroller: 控制,处理客户端请求,如servlet流程图:JavaEE架构简介:Web层,Service层,Dao层三层架构Web层:J..._java ee分层和mvc

随便推点

开发android 输入法,Android输入法开发实例解析 Android开发技术-程序员宅基地

文章浏览阅读1k次。Android输入法开发实例解析 Android开发技术2013 年 4 月 13 日这里我们建立表1为BiHua,同时构建两个字段,字段1为“input”来存放输入的,字段2为“value”为匹配出来的值,这里不难实现比如我们输入“111211”就可以匹配出两个这样笔画的字,分别是“彗”和“慧”,而1笔就可以输入好的字有“一不在有来大地到要可而于下过事”,这里我们可以把常用字优先排到前面。2.五..._安卓输入法案例

QTabWidget 常用样式设置_qt tab样式-程序员宅基地

文章浏览阅读5.7k次,点赞3次,收藏21次。QTabWidget 常用样式设置_qt tab样式

做中学-程序员宅基地

文章浏览阅读116次。作业二--做中学你有什么技能比大多人(超过90%以上)更好?游戏五子棋针对这个技能的获取你有什么成功的经验?第一,多多去查资料,看视频。在初中时,我有一段时间都把精力放在了游戏上,那个时候刚刚接触dota,基本上什么都不懂,但是为了熟悉他们,我平时基本上除了学习之外的时间,大部分都用来去开视频,看比赛,在论坛上看英雄技能介绍,游戏中的小技巧。我高中沉迷于玩五子棋时也是这样,经常去看..._如何通过“做中学”来实现你的目标

@property (copy) NSMutableArray *array; 这个写法会出什么问题_@property(copy)nsmutablearray *array-程序员宅基地

文章浏览阅读2.3k次。我们先回忆一下copy属性的作用,一个属性如果标记了copy,当你调用其setter方法时,他会建立一个索引计数为1的对象,然后释放旧对象。@property (copy) NSMutableArray * a;NSMutableArray* b = [NSMutableArray array];a = b;等同于@property (strong) NSMutable_@property(copy)nsmutablearray *array

sublime说python找不到_sublime配置python开发环境以及遇到的坑-程序员宅基地

文章浏览阅读1k次。最近一直在写python项目,在此之前我用的工具主要是pycharm,由于我的笔记本配置渣,每次打开pycharm后我都要去倒杯水,然后回来看看有没有打开我的项目,时间充足的时候还好,如果有同事或者领导来让你给他改改东西,emmmmm,对不起,跟我一起等电脑先启动pycharm再说。不得不说,pycharm确实强大,但是对于我来说,启动速度是致命的缺点,久而之久sublime就成功闯进了我的视线。..._sublimepythonide could not find python

2019软件外包平台有哪些?_有哪些外包平台-程序员宅基地

文章浏览阅读1.2k次。最新更新:2019/09/07只推荐最靠谱的外包平台。如果您有补充,可以留言。国内外包平台程序员客栈: https://proginn.comcoding码市 :https://mart.coding.net蜻蜓外包 :https://qingting.wok/实现网:https://shixian.com/Oschina众包 https://zb.oschina.net国外包包平..._有哪些外包平台

推荐文章

热门文章

相关标签