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出来?)