线程运行时会遇到两种场景:
- 各个线程需要一个独享的对象
- 线程内需要一个全局对象保存参数,在不同的方法之间传递。
场景1中,使用ThreadLocal持有对象,这个对象只对当前的线程可见,其他线程不可见,故而线程安全。
public class MessageHolder {
private List<Message> messages = Lists.newArrayList();
@SuppressWarnings({"rawtypes", "unchecked"})
private static final ThreadLocal<MessageHolder> holder = new ThreadLocal(){
@Override
protected Object initialValue() {
return new MessageHolder();
}
};
public static void add(Message message) {
holder.get().add(message);
}
public static List<Message> clear() {
ArrayList<Message> list = Lists.newArrayList(holder.get().messages);
holder.remove();
return list;
}
}
如上所示,在新建ThreadLocal对象时覆写initialValue方法,持有MessageHolder 对象,该对象就只对当前线程有效。
场景2中,可以直接用 YOURThreadLocal().set(YOUR_OBJECT) 来设置持有的对象,方便同一个线程中其他方法取出使用 YOURThreadLocal().get()。
两个场景之间的差别在于,场景1中持有对象由开发者控制,所以在初始化时就可以设置,覆写 initialValue();场景2由使用者控制,在业务运行时才知道要持有什么对象,所以使用 set(YOUR_OBJECT) 方法。
由此可见 ThreadLocal 的好处有四:
- 线程安全
- 避免使用 锁 或者 线程安全类 提高效率
- 避免创建太多工具对象
- 避免参数传递的繁琐
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。