java并发之ThreadLocal

不想你离开。 提交于 2020-03-04 07:47:39

ThreadLocal的思考:

描述:

    方法1:传入秒数,new一个SimpleDataFormat对象,返回时间字符串

    方法2:生成两个线程,每个线程都去调用方法1来打印不同秒数的时间

结果:运行正常

进一步思考:要是1000个线程呢?用线程池,生成10线程

进一步思考:在方法1中,每次调用都会new一个SimpleDataFormat对象,浪费开销

解决方法:将SimpleDataFormat作为全局变量

运行结果:线程出现并发冲突问题,会有相同时间结果。原因是多个线程共享了SimpleDataFormat对象。

解决方法:加锁,用synchronized

进一步思考:虽然现在sm只生成了一次,但多个线程在加锁部分部分代码是串行执行的,没有并发,效率低

优化:在线程池有10线程,让每个线程都有自个的sm对象,这样,10线程之间就可以并发执行,sm也没有创建很多个

实现方式: 用ThreadLocal给当前线程赋予独立的变量

另一个场景,服务器接收请求,有用户信息,不同方法使用同一个用户信息。

分析:不同请求对应不同线程,每个线程都用ThreadLocal来保存用户信息,则不会发生冲突,且用户信息也不用作为方法参数传来传去

源码分析: 在Thread对象中,有一个map,key为ThreadLocal对象,value为用户定义的值,这样,每个线程都有独立的变量存储map,且可以保存多个不同的值。

Spring中的应用:RequestContextHolder中用ThreadLocal来保存请求的各种信息RequestAttributes

示例代码:

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 多个线程打印时间练习:多个独立线程打印,打印出不同秒数后的时间
 * 使用了ThreadLocal,线程池中每个线程都有自个的SimpleDateFormat对象,不用重复创建
 */
public class test03 {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        ThreadLocal<SimpleDateFormat> simpleDateFormatThreadLocal
                = new ThreadLocal<SimpleDateFormat>(){
            @Override
            protected SimpleDateFormat initialValue() {
                return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            }
        };

        //可以有多个ThreadLocal来保存多个变量值,用 lambda 表达式简化初始化
        ThreadLocal<String> stringThreadLocal = ThreadLocal.withInitial(()->"test");

        for(int i=0;i<1000;i++){
            final int temp = i;

            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    Date date = new Date(temp*1000);
                    String dateStr = simpleDateFormatThreadLocal.get().format(date);
                    System.out.println(dateStr);   //输出结果不会有重复
                    System.out.println(stringThreadLocal.get());
                }
            });
        }

    }

}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!