java Thread相关类及区别

本文深入探讨了Thread、ThreadGroup、ThreadLocal等概念及其应用。解析了ThreadLocal的工作原理和内部实现细节,包括如何避免内存泄漏。同时对比了ThreadLocal与同步机制的不同之处。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Thread、ThreadGroup、ThreadLocal、ThreadLocalMap、ThreadLocalRandom、InheritableThreadLocal:
将一个线程和对象绑定在一起只有ThreadLocal才能实现;
每个Thread有一个优先级、名字、daemon标识、所属的ThreadGroup、ClassLoader(线程上下文类加载器)、线程id,以及ThreadLocalMap用于存放ThreadLocal变量;
(有currentThread、yield、sleep、start0、stop0、resume0、interrupt0、isInterrupted、isAlive、suspend0、setPriority0、setNativeName、holdsLock、dumpThreads、getThreads等大量native方法;)
(start、setName、join方法为啥加了synchronized?)
(interrupt方法为啥用synchronized同步方法块?)
每个Thread有一个状态state,可以是NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED;
(注意:只是jvm级别的状态,不是OS级别的状态;利用枚举enum State实现;)
Thread也是实现Runnable接口的;
(interrupted方法和interrupt方法的区别?前者只是返回状态,后者执行中断)
(不建议使用stop方法,因为会立即中断线程并释放锁,但线程状态未知;推荐用interrupt!)
(不建议使用suspend方法,因为容易造成死锁;推荐用sleep和wait;)

ThreadGroup封装了Thread数组threads,以及parent父线程组;
(ThreadGroup之间的关系是树的关系,而Thread与ThreadGroup的关系是元素与集合的关系;)
(一个Thread必然有所属ThreadGroup?)
(activeCount方法估计此线程组中活动线程的数目;)
(interrupt方法中断线程组中的所有线程;)

ThreadLocal通常是私有的、静态的字段,能够把某种状态关联到某个线程(比如用户id、事务id);
(各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用;)
(ThreadLocal常见的应用场景如每个线程访问数据库,需要一个独立的Session会话;)
(ThreadLocal核心方法是get、set、remove;)
(使用ThreadLocal最好定义为private static final类型;)
(在线程池中使用ThreadLocal,如果没有remove,会导致数据污染;)
(ThreadLocal可以避免每次调用方法都要传递对象的麻烦;)
内部类ThreadLocalMap用于存放多个ThreadLocal变量,是一个定制的hash map;
(ThreadLocalMap是package private的,所以不能继承和外部使用)
(ThreadLocalMap的内部类Entry代表一个节点,即ThreadLocal变量;)
(ThreadLocalMap利用Entry[] table数组维护hash map所有节点;初始容量16,且resize是双倍扩容,因此扩容后也是2的幂方;)
(ThreadLocalMap利用开放定址法之线性探查再散列来解决哈希冲突,用nextIndex方法寻找下一个可行的索引位置;)
(注意:既然是线性探查再散列,就没有也不需要链表了;nextIndex方法每次取下一个相邻位置,即i=i+1)
(这种解决冲突的方式效率较低,所以建议每个线程只存一个ThreadLocal变量,避免哈希冲突;)
(注意:Entry节点封装了key和value,其中key是WeakReferences的,但value不是;)
(由于key是弱引用,value是强引用,发生GC时Key会被回收,而Value不会,所以使用完ThreadLocal后,要调用remove方法;)
(为啥设计key为弱,value为强?因为jdk作者只需要关注Entry被清除,而不用管value,value被外部使用;)
https://www.jianshu.com/p/98b68c97df9b
http://ifeve.com/threadlocal使用/
https://www.jianshu.com/p/a1cd61fa22da (ThreadLocal内存泄漏)
https://blog.youkuaiyun.com/ZYC88888/article/details/81239094 (java ThreadLocal 使用)

InheritableThreadLocal是ThreadLocal的子类,支持从父线程继承值到子线程;

ThreadLocalRandom是一个随机数发生器,和Random有关(是它的子类),和ThreadLocal关系不大;

ThreadLocal和同步机制的区别:
同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式;
前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响;

ThreadLocal不是解决线程安全问题,而是为了共享?(不是线程之间共享,而是方法之间的共享?)
(如果是这样,那和同步比较有什么意义?有一点道理,如果是为了线程安全,那直接用私有变量不就行了,为啥搞个ThreadLocal出来?)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值