线程运行时会遇到两种场景:

  1. 各个线程需要一个独享的对象
  2. 线程内需要一个全局对象保存参数,在不同的方法之间传递。

场景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 的好处有四:

  1. 线程安全
  2. 避免使用 锁 或者 线程安全类 提高效率
  3. 避免创建太多工具对象
  4. 避免参数传递的繁琐

Fox_Valentin
1 声望1 粉丝