多线程-线程封闭
线程封闭
当访问共享变量时,就要用到同步,一种避免同步的方式就是不共享数据。如果仅在单线程中使用数据,就不需要同步,这种技术被称为线程封闭。
Ad-hoc线程封闭
Ad-hoc线程封闭完全由程序实现,这种线程封闭比较脆弱,因为没有任何语言特性,变量修饰符等可以将某个变量封闭到单个线程中。
对于volatile修饰变量,只要保证只能由一个线程对变量进行写入操作,其他线程只读取该共享变量的值,则可以保证线程安全。
由于Ad-hoc线程封闭的脆弱性,在程序中尽量不要使用,应该使用更强的线程封闭技术(栈封闭和ThreadLocal等)
栈封闭
栈封闭也被称为线程内部使用或线程局部使用,在栈封闭中,只有局部变量才能访问对象。在使用栈封闭时,需要主要防止对象逸出。
ThreadLocal类
ThreadLocal类可以将变量绑定到线程中。 例如在一个线程中,使用mysql事务时,开启事务和事务中所有sql的执行,以及事务的提交都需要使用同一个MySQL链接,因此在获取链接的时候,可以使用ThreadLocal类,来保证在该线程中获取的永远都是同一个链接。
public class ConnectionUtils {
static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();
//获取链接的方法
public static Connection getConnection() {
/*先从ThreadLocal对象中获取,如果为空 则创建链接,并绑定到该线程上 threadLocal.set(connection);*/
Connection connection = threadLocal.get();
if (connection == null) {
connection = createConnection(URL);
threadLocal.set(connection);
}
return connection;
}
}
当某个线程初次调用ThreadLocal.get方法时,就会调用initialValue来获取初始值。从概念上看,可以将ThreadLocal理解为包含了Map<Thread,T>对象,其中保存了特定于该线程的值。但ThreadLocal的实现并非如此。这些特定于线程的值保存在Thread对象中,当线程终止后这些值就会作为垃圾回收。