ThreadLocal原理和java类全局静态变量在多线程中数据混乱
问题
引⾃:
⼀般想要在不同⽅法中传递上下⽂数据,会使⽤全局变量,⽽想在不同类中传递上下⽂数据,则会使⽤全局静态变量,因为静态全局变量是属于类⼀直存在的,但是在多线程操作状态下,java类全局静态变量在多线程中会出现数据混乱问题,因为多个线程同时对同⼀个静态变量操作时,⽆法确保每个线程取出的值是⾃⼰放的值。
这时就出现了ThreadLocal:
ThreadLocal众所周知,可以把变量绑定到到某⼀线程上,这个thread⾥有个静态内部类(可以理解为⼀个全局变量ThreadLocalMap),
其泛型为<ThreadLocal,Object>
⽽threadlocal在执⾏set⽅法时会先获取当前线程(Thread t = Thread.currentThread()),使⽤当前线程去拿到⼀个ThreadLocalMap,如果这个map不为空,说明当前线程之前有绑定过的map,就更新这个这个map的value,如果没有就以⾃⾝为key把值放到map中,从⽽实现变量与线程的绑定。
关于ThreadLocal的⽤法,有这两种说法:
1.传递上下⽂变量,减少程序复杂度
2.空间换时间,解决并发下对临界资源的访问。
其次还要注意的是:ThreadLocal和同步机制synchonzied相⽐
(Synchronized⽤于线程间的数据共享,⽽ThreadLocal则⽤于线程间的数据隔离。)
1.1.synchonzied同步机制是为了实现同步多线程对相同资源的并发访问控制。同步的主要⽬的是保证多线程间的数据共享。同步会带来巨⼤的性能开销,所以同步操作应该是细粒度的(对象中的不同元素使⽤不同的锁,⽽不是整个对象⼀个锁)。如果同步使⽤得当,带来的性能开销是微不⾜道的。使⽤同步真正的风险是复杂性和可能破坏资源安全,⽽不是性能。
2.ThreadLocal以空间换取时间,提供了⼀种⾮常简便的多线程实现⽅式。因为多个线程并发访问⽆需进⾏等待,所以使⽤ThreadLocal会获得更⼤的性能。
java上下文context3.ThreadLocal中的对象,通常都是⽐较⼩的对象。另外使⽤ThreadLocal不能使⽤原⼦类型,只能使⽤Object类型。ThreadLocal的使⽤⽐synchronized要简单得多。
4.synchronized是利⽤锁的机制,使变量或代码块在某⼀时该只能被⼀个线程访问。⽽ThreadLocal为每⼀个线程都提供了变量的副本,使得每个线程在某⼀时间访问到的并不是同⼀个对象,这样就隔离了多个线程对数据的数据共享。⽽Synchronized却正好相反,它⽤于在多个线程间通信时能够获得数据共享。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论