美文网首页
ThreadLocal设计思想

ThreadLocal设计思想

作者: 手打丸子 | 来源:发表于2020-02-16 16:24 被阅读0次

    之前分享过TheadLocal的创建销毁原则,并且使用代码进行了测试ThreadLocal内存泄露
    使用ThreadLocal的目的:
    1.又希望并发安全,又不想使用锁;
    2.线程间隔离,且希望线程内任务获取的是同一个对象,如spring中事务模块将数据库连接放在ThreadLocal中;

    那怎么使用才是比较安全的使用方式呢
    根据生命周期划分,主要分为三种情况

    1.与Thread生命周期相同
    一般适用于线程不安全的工具类,比如SimpleDateFormat;
    或者数据库连接之类的,在spring中有使用,不仅仅保证了并发安全,也保证了同一个线程拿到的同一个connection,来保证事务性;
    放在

    //使用ThreadLocal代替原来的new SimpleDateFormat
        private static final ThreadLocal<SimpleDateFormat> dateFormatter = new   ThreadLocal<SimpleDateFormat>(){
            //放在initialValue中会在首次get的时候初始化
            @Override
            protected SimpleDateFormat initialValue() {
                return  new SimpleDateFormat("yyyy-MM-dd");
            }
        };
    
    //使用时
    dateFormatter.get().format(new Date());
    
    

    2.与task生命周期相同
    这里有两种使用方式

    一种是嵌套方式

       private static final ThreadLocal<Object> threadLocal = new   ThreadLocal<Object>();
    
    try{
      threadLocal.set(new Object());
      //这里做真的业务
      doBiz();
    }finally{
      threadLocal.remove();
    }
    

    当然,不嵌套也是可以的,需要有明确的业务入口

       private static final ThreadLocal<Object> threadLocal = new   ThreadLocal<Object>();
    
      //在业务开始前完成ThreadLocal的设置
      threadLocal.set(new Object());
      doBiz();
    

    3.小于task生命周期
    这种情况只能使用嵌套方式
    但是由于线程内任何地方都可以设置该ThreadLocal
    所以,一定要封锁住set的权限,只能在一个地方set,如果那里都能访问到并且set,就乱套了
    当然,你有胆量的话,能整理清楚复杂的业务逻辑,保证变量不出问题,就大胆随意用吧

      public class BusinessHandler {
    
            private static ThreadLocal<String> name = new ThreadLocal<>();
    
            private static void setName(String newName){
                name.set(newName);
            }
    
            public static String getName(){
                return name.get();
            }
    
            public void handle(){
                String thisName = "new name";
                setName(thisName);
                doBiz();
            } 
    }
    
    //在其他地方使用该ThreadLocal
    public void doBiz() {
                // use name
                BusinessHandler.getName();
            }
    

    相关文章

      网友评论

          本文标题:ThreadLocal设计思想

          本文链接:https://www.haomeiwen.com/subject/wawpfhtx.html