首页 > 试题广场 >

下面有关java threadlocal说法正确的有?

[不定项选择题]
下面有关 Java ThreadLocal 说法正确的有?
  • ThreadLocal存放的值是线程封闭,线程间互斥的,主要用于线程内共享一些数据,避免通过参数来传递
  • 线程的角度看,每个线程都保持一个对其线程局部变量副本的隐式引用,只要线程是活动的并且 ThreadLocal 实例是可访问的;在线程消失之后,其线程局部实例的所有副本都会被垃圾回收
  • 在Thread类中有一个Map,用于存储每一个线程的变量的副本。
  • 对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式
ThreadLocal类用来提供线程内部的局部变量。这种变量在多线程环境下访问(通过get或set方法访问)时能保证各个线程里的变量相对独立于其他线程内的变量。ThreadLocal实例通常来说都是private static类型的,用于关联线程和线程的上下文。 可以总结为一句话:ThreadLocal的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度。 举个例子,我出门需要先坐公交再做地铁,这里的坐公交和坐地铁就好比是同一个线程内的两个函数,我就是一个线程,我要完成这两个函数都需要同一个东西:公交卡(北京公交和地铁都使用公交卡),那么我为了不向这两个函数都传递公交卡这个变量(相当于不是一直带着公交卡上路),我可以这么做:将公交卡事先交给一个机构,当我需要刷卡的时候再向这个机构要公交卡(当然每次拿的都是同一张公交卡)。这样就能达到只要是我(同一个线程)需要公交卡,何时何地都能向这个机构要的目的。 有人要说了:你可以将公交卡设置为全局变量啊,这样不是也能何时何地都能取公交卡吗?但是如果有很多个人(很多个线程)呢?大家可不能都使用同一张公交卡吧(我们假设公交卡是实名认证的),这样不就乱套了嘛。现在明白了吧?这就是ThreadLocal设计的初衷:提供线程内部的局部变量,在本线程内随时随地可取,隔离其他线程。
发表于 2018-03-09 12:12:05 回复(19)
Threadlocal并不是用来共享数据的,而且也不能解决线程同步的问题,感觉AD都是错的
发表于 2016-09-05 10:07:36 回复(1)
ThreadLocal类用于创建一个线程本地变量
在Thread中有一个成员变量ThreadLocals,该变量的类型是ThreadLocalMap,也就是一个Map,它的键是threadLocal,值为就是变量的副本。通过ThreadLocal的get()方法可以获取该线程变量的本地副本,在get方法之前要先set,否则就要重写initialValue()方法。
ThreadLocal的使用场景:
        数据库连接:在多线程中,如果使用懒汉式的单例模式创建Connection对象,由于该对象是共享的,那么必须要使用同步方法保证线程安全,这样当一个线程在连接数据库时,那么另外一个线程只能等待。这样就造成性能降低。如果改为哪里要连接数据库就来进行连接,那么就会频繁的对数据库进行连接,性能还是不高。这时使用ThreadLocal就可以既可以保证线程安全又可以让性能不会太低。但是ThreadLocal的缺点时占用了较多的空间。

发表于 2015-08-26 20:51:12 回复(7)
对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。
发表于 2017-05-24 15:15:21 回复(0)
  1. private static final ThreadLocal threadSession = new ThreadLocal();  
  2.   
  3. public static Session getSession() throws InfrastructureException {  
  4.     Session s = (Session) threadSession.get();  
  5.     try {  
  6.         if (s == null) {  
  7.             s = getSessionFactory().openSession();  
  8.             threadSession.set(s);  
  9.         }  
  10.     } catch (HibernateException ex) {  
  11.         throw new InfrastructureException(ex);  
  12.     }  
  13.     return s;  
  14. }  
“ThreadLocal存放的值是线程封闭,线程间互斥的”这个在《java并发编程》P.37面有讲
“主要用于线程内共享一些数据,避免通过参数来传递”
我们通过hibernate的例子,可以看出
这个session在不同线程中是不同的,但是在同一个线程中是相同的。
可以直接通过getSession获取实例,所以避免了参数传递,实现线程内共享。
所以A选项正确
 
发表于 2015-08-06 20:05:36 回复(5)
BCD
ThreadLocal解决并发访问线程安全问题,故A错误
发表于 2015-01-04 22:08:30 回复(6)
ThreadLocal和多线程并发没有什么关系。ThreadLocal模式是为了解决单线程内的跨类跨方法调用的 ThreadLocal不是用来解决对象共享访问问题的,而主要是提供了保持对象的方法和避免参数传递的方便的对象访问方式。一般情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的。各个线程中访问的是不同的对象。 所以A是对的
发表于 2016-08-14 15:54:55 回复(0)
数据库连接时之所以使用threadlocal是因为数据库连接池,连接池里面很多connection,导致同一个事务(可理解为涉及多个DAO)每次获取的connection不是同一个。所以为了解决这个问题,就用threadlocal,把当前的connection放到当前线程里,如果是这个线程就获取得到对应的connection。
发表于 2016-08-07 10:27:17 回复(0)
C选项的源代码如下:

发表于 2017-08-08 09:36:03 回复(2)
不是使用的副本么,为什么A选项说的线程间互斥是正确的,没有形成互斥吧,各用各的
发表于 2019-06-05 10:22:33 回复(0)
C 是错误的啊,ThreadLocalMap 的数据结构实质上是一个数组啊 并不是一个map。求大神给指导指导
发表于 2015-06-22 11:54:58 回复(1)
ThreadLocal和多线程并发没有什么关系。ThreadLocal模式是为了解决单线程内的跨类跨方法调用的
ThreadLocal不是用来解决对象共享访问问题的,而主要是提供了保持对象的方法和避免参数传递的方便的对象访问方式。一般情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的。各个线程中访问的是不同的对象。
所以A是对的
发表于 2015-04-21 14:05:04 回复(1)
A不对啊,ThreadLocal并不存放值啊,值都存在Thread里啊
发表于 2023-07-13 13:43:48 回复(0)
ThreadLocal不是单线程没共享数据吗?d为什么对了
发表于 2021-08-21 08:11:23 回复(0)
选项D是有争议的,使用了ThreadLocal之后还能称之为是资源共享吗??资源在各线程之间都隔离了还能称之为共享。强行解释的话应该是对于数据库连接这种可共享可隔离的共享资源,之前是只有一处存储,现在每个线程都去存储,并且访问时马上就能访问当前线程中的连接池,所以“以空间换时间”的说法还欧克。
发表于 2019-07-07 14:05:13 回复(0)
A选项,难道不应该是用于数据独立么?
发表于 2016-12-15 10:13:35 回复(2)
从线程的角度看,每个线程都保持一个对其线程局部变量副本的隐式引用,只要线程是活动的并且 ThreadLocal 实例是可访问的;在线程消失之后,其线程局部实例的所有副本都会被垃圾回收(除非存在对这些副本的其他引用)。
B怎么会正确 “ 存在对这些副本的其他引用 ”不就不成立了...
发表于 2015-08-12 17:12:45 回复(3)
关于“变量的副本”指的是值的副本,如果是引用类型则是引用的副本,没毛病
发表于 2023-11-18 23:57:31 回复(0)
    Thread对象中通过维护了一个ThreadLocal.ThreadLocalMap类型的threadLocals变量实现线程间变量隔离,并维护了一个ThreadLocal.ThreadLocalMap类型的inheritableThreadLocals变量实现线程间变量的继承,是否继承由线程初始化时inheritThreadLocals参数进行决定,默认不继承。
    ThreadLocal中核心存储的类为ThreadLocalMap类,ThreadLocalMap类本身是一个定制化的Map,这个Map以当前ThreadLocal对象作为key值进行K-V存储。ThreadLocalMap的初始化容量为16,扩容因子为2/3。
    ThreadLocalMap在进行存储时,会获取当前this对象的threadLocalHashCode值(这也是为什么使用ThreadLocal作为key的原因),该值是唯一的,只在ThreadLocalMap中有用,使用Unsafe提供AtomicInt类操作获取。
    ThreadLocalMap中进行存储的基本单位为Entry数组,数组下标通过threadLocalHashCode进行&运算并根据当前数组长度进行自动扩容。

发表于 2023-07-18 22:58:27 回复(0)
ThreadLocal是Java中的一个线程本地变量,它为每个线程提供了一个独立的变量副本,使得每个线程都可以独立地改变自己的副本,而不会影响其他线程的副本。可以将ThreadLocal看作是一个容器,用于存储每个线程的私有数据。

ThreadLocal的主要作用是在多线程环境下,提供线程安全的变量副本,避免了多线程之间共享变量带来的线程安全问题,同时也提高了线程执行效率。

以下是一个简单的ThreadLocal使用示例
public class MyThread implements Runnable {
    private ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();//定义了一个私有的ThreadLocal变量threadLocal,它的泛型参数为Integer类型,用于存储每个线程的私有数
    public void run() {
        threadLocal.set((int) (Math.random() * 1000));
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("线程" + Thread.currentThread().getName() + "的变量值为:" + threadLocal.get());
    }
}

public class Main {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        new Thread(myThread, "线程1").start();//注意:
          new Thread(myThread, "线程1");//这种方式创建线程时,参数myThread是一个实现了Runnable接口的类的对象,它封装了要执行的任务。而第二个参数"线程1"则是线程的名称。
        new Thread(myThread, "线程2").start();
    }
}

在上述示例中,我们定义了一个名为MyThread的类,该类实现了Runnable接口,并在其内部定义了一个ThreadLocal变量threadLocal。在run()方法中,我们使用threadLocal.set()方法将线程的私有变量设置为一个随机数,并使用threadLocal.get()方法获取线程的私有变量,并将其打印输出到控制台。

在主函数中,我们创建了两个线程,分别为线程1和线程2,并将它们启动。由于每个线程都有自己的ThreadLocal变量副本,因此线程1和线程2将拥有不同的变量副本,并且它们的变量值不会相互影响。

需要注意的是,在使用ThreadLocal时,需要注意内存泄漏问题,因为ThreadLocal变量是与线程绑定的,如果线程一直存在,而ThreadLocal变量没有被清除,则可能导致内存泄漏。因此,在使用ThreadLocal时,需要及时清理ThreadLocal变量,以避免内存泄漏问题。

dLocal变量的值

new Thread(myThread, "线程1");调用的是什么构造函数


发表于 2023-05-21 23:08:06 回复(0)