并发编程实战(4): 线程封闭

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wen_fei/article/details/84258738

同步

当访问共享可变数据时,需要使用同步技术保证数据的一致性。如果不使用同步,则需要避免共享数据。如果仅仅在单线程内访问数据,就不需要使用同步,这种技术被称为线程封闭(Thread Confinement。例如Swing、JDBC等都大量使用了此技术。常见的线程封闭技术主要有以下几种:

Ad-hoc线程封闭

这种线程封闭主要是指,维护线程封闭性的职责完全由程序创建者承担,所以非常脆弱。这种技术一般很少使用。

栈封闭

所谓栈封闭,其实就是通过局部变量来实现。在栈封闭中,只能通过局部变量来访问对象。多个线程访问一个方法,此方法中的局部变量都会被拷贝一分儿到线程栈中。所以局部变量是不被多个线程所共享的,也就不会出现并发问题。它们位于执行线程的栈中,其他线程无法访问这个栈。

栈封闭比Ad-hoc更易于维护和健壮。注意:在使用栈封闭技术时,要保证局部对象不会逸出。

ThreadLocal类

ThreadLocal类能使线程中的某个值与保存值的对象关联起来,它提供了get、set方法,这些方法为每个使用该变量的线程保存一份独立的副本,因此get总是set当前线程的set最新值。

ThreadLocal 是一个线程级别的局部变量,并非“本地线程”。ThreadLocal 为每个使用该变量的线程提供了一个独立的变量副本,每个线程修改副本时不影响其它线程对象的副本。

ThreadLocal 实例通常作为静态的私有的(private static)字段出现在一个类中,这个类用来关联一个线程。

当多个线程访问 ThreadLocal 实例时,每个线程维护 ThreadLocal 提供的独立的变量副本。

ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单:在ThreadLocal类中有一个Map,用于存储每一个线程的变量副本,Map中元素的键为线程对象,而值对应线程的变量副本。

对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。

猜你喜欢

转载自blog.csdn.net/wen_fei/article/details/84258738
今日推荐