这里使用 ThreadLocal 重新实现该功能如下所示。
- public class SessionHandler {
- public static ThreadLocal<Session> session = new ThreadLocal<Session>();
- @Data
- public static class Session {
- private String id;
- private String user;
- private String status;
- }
- public void createSession() {
- session.set(new Session());
- }
- public String getUser() {
- return session.get().getUser();
- }
- public String getStatus() {
- return session.get().getStatus();
- }
- public void setStatus(String status) {
- session.get().setStatus(status);
- }
- public static void main(String[] args) {
- new Thread(() -> {
- SessionHandler handler = new SessionHandler();
- handler.getStatus();
- handler.getUser();
- handler.setStatus("close");
- handler.getStatus();
- }).start();
- }
- }
使用 ThreadLocal 改造后的代码,不再需要在各个方法间传递 Session 对象,并且也非常轻松的保证了每个线程拥有自己独立的实例。
如果单看其中某一点,替代方法很多。比如可通过在线程内创建局部变量可实现每个线程有自己的实例,使用静态变量可实现变量在方法间的共享。但如果要同时满足变量在线程间的隔离与方法间的共享,ThreadLocal再合适不过。
七、总结
- ThreadLocal 并不解决线程间共享数据的问题
- ThreadLocal 通过隐式的在不同线程内创建独立实例副本避免了实例线程安全的问题
- 每个线程持有一个 Map 并维护了 ThreadLocal 对象与具体实例的映射,该 Map 由于只被持有它的线程访问,故不存在线程安全以及锁的问题
- ThreadLocalMap 的 Entry 对 ThreadLocal 的引用为弱引用,避免了 ThreadLocal 对象无法被回收的问题
- ThreadLocalMap 的 set 方法通过调用 replaceStaleEntry 方法回收键为 null 的 Entry 对象的值(即为具体实例)以及 Entry 对象本身从而防止内存泄漏
- ThreadLocal 适用于变量在线程间隔离且在方法间共享的场景
【本文为51CTO专栏作者“郭俊”的原创稿件,转载请联系原作者】
戳这里,看该作者更多好文
【编辑推荐】
- 全栈必备 你需要了解的Java编程基础
- 深入理解多线程(二)—— Java的对象模型
- 外媒速递:下一代Java新特性展望——Java JDK 10
- 作为你的第一门语言,初学Java时是什么感受?
- JavaScript写库前的准备工作
【责任编辑:赵宁宁 TEL:(010)68476606】
点赞 0 (编辑:PHP编程网 - 黄冈站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|