Java之ThreadLocal使用常见和方式有哪些

发布时间:2021-08-09 13:41:46 作者:小新
来源:亿速云 阅读:163

这篇文章主要介绍了Java之ThreadLocal使用常见和方式有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

1 两大使用场景-ThreadLocal的用途

2 典型场景1:每个线程需要一个独享的对象

每个Thread内有自己的实例副本,不共享;

举例:SimpleDateFormat。(当多个线程共用这样一个SimpleDateFormat,但是这个类是不安全的)

package threadlocal;

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

/**
 * 描述:     利用ThreadLocal,给每个线程分配自己的dateFormat对象,保证了线程安全,高效利用内存
 */
public class ThreadLocalNormalUsage05 {

    public static ExecutorService threadPool = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 1000; i++) {
            int finalI = i;
            threadPool.submit(new Runnable() {
                @Override
                public void run() {
                    String date = new ThreadLocalNormalUsage05().date(finalI);
                    System.out.println(date);
                }
            });
        }
        threadPool.shutdown();
    }

    public String date(int seconds) {
        //参数的单位是毫秒,从1970.1.1 00:00:00 GMT计时
        Date date = new Date(1000 * seconds);
//        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat dateFormat = ThreadSafeFormatter.dateFormatThreadLocal2.get();
        return dateFormat.format(date);
    }
}

class ThreadSafeFormatter {

    public static ThreadLocal<SimpleDateFormat> dateFormatThreadLocal = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
    };

    public static ThreadLocal<SimpleDateFormat> dateFormatThreadLocal2 = ThreadLocal
            .withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
}

3 典型场景2:当前用户信息需要被线程内所有方法共享

每个线程内需要保存全局变量,可以让不同方法直接使用,避免参数传递的麻烦

package threadlocal;

/**
 * 描述:     演示ThreadLocal用法2:避免传递参数的麻烦
 */
public class ThreadLocalNormalUsage06 {

    public static void main(String[] args) {
        new Service1().process("");

    }
}

class Service1 {

    public void process(String name) {
        User user = new User("超哥");
        UserContextHolder.holder.set(user);
        new Service2().process();
    }
}

class Service2 {

    public void process() {
        User user = UserContextHolder.holder.get();
        ThreadSafeFormatter.dateFormatThreadLocal.get();
        System.out.println("Service2拿到用户名:" + user.name);
        new Service3().process();
    }
}

class Service3 {

    public void process() {
        User user = UserContextHolder.holder.get();
        System.out.println("Service3拿到用户名:" + user.name);
        UserContextHolder.holder.remove();
    }
}

class UserContextHolder {

    public static ThreadLocal<User> holder = new ThreadLocal<>();


}

class User {

    String name;

    public User(String name) {
        this.name = name;
    }
}

注意点:

4 ThreadLocal方法使用总结

场景一:initialValue

在ThreadLocal第一次get的时候把对象给初始化出来,对象的初始化时机可以由我们控制。

场景二:set

如果需要保存到ThreadLocal里面的对象的生成时机不由我们随意控制。例如拦截器生成的用户信息,用ThreadLocal.set直接放到ThreadLocal当中。

5 ThreadLocal原理

理清Thread,ThreadLocalMap以及ThreadLocal

Java之ThreadLocal使用常见和方式有哪些

主要方法介绍

ThreadLocalMap发生冲突之后,会用线性探测法。

6 ThreadLocal使用问题内存泄露

什么是内存泄露:某个对象不再有用,但是占用的内存却不能被回收。

Value的泄露

如何避免内存泄露呢?

7 实际应用场景-在spring中的实例分析

感谢你能够认真阅读完这篇文章,希望小编分享的“Java之ThreadLocal使用常见和方式有哪些”这篇文章对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,更多相关知识等着你来学习!

推荐阅读:
  1. 怎么在java中使用ThreadLocal
  2. 使用ThreadLocal的作用有哪些

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java threadlocal

上一篇:python中自带缓存lru_cache怎么用

下一篇:python最短路径算法怎么选择

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》