【并发编程】线程安全策略

线程封闭

线程封闭

把对象封装到一个线程里,只有这个线程能看到这个对象。html

实现线程封闭

Ad-hoc 线程封闭:程序控制实现,最糟糕,忽略
堆栈封闭:局部变量,无并发问题
ThreadLocal 线程封闭:特别好的封闭方法java

ThreadLocal 实例保存登陆用户信息编程

public class RequestHolder {
    private final static ThreadLocal<Long> requestHolder = new ThreadLocal<>();

    /**
     * 添加数据
     * 在filter里将登陆用户信息存入ThreadLocal
     * 若是不使用ThreadLocal,咱们会须要将request一直透传
     * @param id
     */
    public static void add(Long id){
        // ThreadLocal 内部维护一个map,key为当前线程名,value为当前set的变量
        requestHolder.set(id);
    }

    /**
     * 获取数据
     * @return
     */
    public static Long getId(){
        return requestHolder.get();
    }

    /**
     * 移除变量信息
     * 若是不移除,那么变量不会释放掉,会形成内存泄漏
     * 在接口处理完之后进行处理(interceptor)
     */
    public static void remove(){
        requestHolder.remove();
    }
}

线程不安全的类与写法

1.StringBuilder 线程不安全,StringBuffer线程安全
缘由:StringBuffer几乎全部的方法都加了synchronized关键字。安全

2.SimpleDateFormat
SimpleDateFormat 在多线程共享使用的时候回抛出转换异常,应该才用堆栈封闭在每次调用方法的时候在方法里建立一个SimpleDateFormat。
另外一种方式是使用joda-time的DateTimeFormatter(推荐使用)。多线程

3.ArrayList,HashMap,HashSet等Collections并发

4.先检查再执行高并发

// 非原子性
if(condition(a)){
  handle(a);
}

同步容器

如今使用的比较少,主要使用并发容器。
ArrayList->Vector,Stack
HashMap->HashTable工具

Collections.synchronizedXXX (list,set,map)ui

并发容器

J.U.C下的工具类:【并发编程】【JDK源码】JDK的(J.U.C)java.util.concurrent包结构线程

ArrayList->CopyOnWriteArrayList
HashSet/TreeSet->CopyOnWriteArraySet/ConcurrentSkipListSet
HashMap/TreeMap->ConcurrentHashMap/ConcurrentSkipListMap

安全共享对象策略

安全地共享对象包括如下几种策略:

线程限制:一个被线程限制的对象,由线程独占,而且只能被占有它的线程修改。
共享只读:一个共享只读的对象,在没有额外同步的状况下,能够被多个线程并发访问,可是任何线程都不能修改它。
线程安全对象:一个线程安全的对象或者容器,在内部经过同步机制来保证线程安全,因此其余线程无需额外的同步就能够经过公共接口随意访问它。
被守护对象:被守护对象只能经过获取特定的锁来访问。

参考资料:
慕课网高并发实战(六)- 线程安全策略

相关文章
相关标签/搜索