threadlocal和currentHashMap区别

小编 430

threadlocal和currentHashMap区别有:1.基础概念的区别;2.使用场景的区别;3.实现原理的区别。基础概念的区别在于,threadlocal是一个类,是一个本地线程,提供了一种线程安全的方式;而ConcurrentHashMap是一个存放键值对的容器,并且是线程安全的。

1.基础概念的区别

threadlocal是一个类,是一个本地线程,提供了一种线程安全的方式,用来避免共享数据(线程变量隔离)。将类变量放到threadlocal类型的对象中,使变量在每个线程中都有独立拷贝,不会出现一个线程读取变量时而被另一个线程修改的现象。

ConcurrentHashMap是一个存放键值(key/value )对的容器,并且是线程安全的。它使用分段锁的思想,对于不同的数据段使用不同的锁,可以支持多个线程同时访问不同的数据段,这样线程之间就不存在锁竞争,从而提高了并发效率。

2.使用场景的区别

threadlocal的使用场景主要有三个:一是,方便同一个线程使用某一对象,避免不必要的参数传递;二是,线程间数据隔离,即每个线程在自己线程里使用自己的局部变量,各线程间的ThreadLocal对象互不影响;三是,获取数据库连接、Session、关联ID(比如日志的uniqueID,方便串起多个日志)。

currentHashMap适用于多个线程同时写/删除操作的场景,这些实际的场景总结如下:一是,Binder AIDL通信,binder的server端是一个线程池,可以接受多个客户端的请求,此时客户端如果同时请求修改server的变量时,需要线程同步操作,可以使用;二是,数据埋点场景,例如某个页面或者操作可能是多个线程同时操作,要改变某一个变量的值时,可以使用。

3.实现原理的区别

(1)threadlocal的实现原理

每一个线程都有一个对应的Thread对象,而Thread类有一个成员变量,它是一个Map集合,这个Map集合的key就是ThreadLocal的引用,而value就是当前线程在key所对应的ThreadLocal中存储的值。当某个线程需要获取存储在ThreadLocal变量中的值时,ThreadLocal底层会获取当前线程的Thread对象中的Map集合,然后以ThreadLocal作为key,从Map集合中查找value值。这就是ThreadLocal实现线程独立的原理。也就是说,ThreadLocal能够做到线程独立,是因为值并不存在ThreadLocal中,而是存储在线程对象中。

(2)currentHashMap的实现原理

在JDK8及以上的版本中,currentHashMap的底层数据结构依然采用“数组+链表+红黑树”,但是在实现线程安全性方面,抛弃了JDK7版本的 Segment分段锁的概念,而是采用了synchronized + CAS 算法来保证线程安全。在ConcurrentHashMap中,大量使用Unsafe.compareAndSwapXXX的方法,这类方法是利用一个CAS算法实现无锁化的修改值操作,可以大大减少使用加锁造成的性能消耗。这个算法的基本思想就是不断比较当前内存中的变量值和你预期变量值是否相等;如果相等,则接受修改的值,否则拒绝你的而操作。因为当前线程中的值已经不是最新的值,你的修改很可能会覆盖掉其他线程修改的结果。

延伸阅读

什么是线程安全

线程安全是应用于多线程代码的一种计算机编程概念,它确保多个线程能够按照程序的设计正确的访问共享数据结构。或者再贴近编程语言的角度一点来讲,线程安全指的是同时最少有两个及以上的线程操作共享的数据区域,并且至少有一个是写操作。线程安全的级别主要有三种:

1.线程安全:这种情况下其实没有线程安全问题,比如上面的例子中,每个人都有自己专用的卫生间,所以不会存在竞争问题。

2.条件安全:顾名思义是有条件的,所有人共用几个卫生间,抢到资源的就把门关上,通过门来隔离资源,后面的人就在外面等待直到里面的人出来。

3.不安全:这种情况下连门都没有,所以并不能很好保证资源安全,所以这种情况较好不能让同时让多个人直接使用。

回复

我来回复
  • 暂无回复内容

注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部