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


    线程封闭

    线程封闭

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

    实现线程封闭

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

    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)

    并发容器

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

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

    安全共享对象策略

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

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

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

  • 相关阅读:
    高斯消元
    Luogu P2068 统计和
    Luogu P1892 [BOI2003]团伙
    Luogu P2866 [USACO06NOV]糟糕的一天Bad Hair Day
    Luogu P3916 图的遍历
    Luogu P1041 [2003NOIP提高组]传染病控制
    Luogu P3901 数列找不同
    Luogu 2951 捉迷藏Hide and Seek
    Luogu P1550 打井Watering Hole
    洛谷——P1044 栈
  • 原文地址:https://www.cnblogs.com/z00377750/p/9231785.html
Copyright © 2020-2023  润新知