JAVA多线程设计模式篇 12、Thread-Specific Storage模式——给我个柜子

Java多线程:ThreadLocal实战与应用场景解析
本文详细介绍了Java中的ThreadLocal,通过示例展示了如何使用ThreadLocal实现线程间的变量隔离。ThreadLocal常用于创建线程特有的数据库连接和session会话,确保线程安全。此外,还提供了开源项目链接供读者深入学习。

多线程环境中即然共用资源这么困难,那么就干脆不要共用,何不为每个执行绪创造一个资源的复本,将每一个执行绪存取资料的行为加以隔离。

Thread Specific Storage模式通过不共享变量实现了线程安全,并由此自然地避免了与锁的消耗及与之有关的问题。

Thread Specific Storage模式的基础是为每个线程“装备”一个线程特有存储(Thread Specific Storage)。线程特有存储可以理解为一个Map。该Map存放了若干个条目(Entry)。每个条目中的值(Value)为一个线程特有对象,键(Key)为ThreadLocal对象。

1. ThreadLocal的使用示例

定义了两个ThreadLocal类型的变量,线程t1设置的值,对于线程t2是不可见的。

public class ThreadLocalTest1 {
    private static ThreadLocal<String> thl1 = new ThreadLocal<>();
    private static ThreadLocal<Integer> thl2 = new ThreadLocal<>();

    public static void main(String[] args) {
        Thread t1 = new Thread(()->{
            thl1.set("abc");
            thl2.set(12);
            thl1.remove();
            thl2.remove();
            System.out.println(thl1.get()+","+ thl2.get());
        });

        Thread t2 = new Thread(()->{
            System.out.println(thl1.get()+","+ thl2.get());
        });

        t1.start();
        t2.start();
    }
}

运行结果:

ThreadLocal

2. ThreadLocal的使用场景

2.1 线程隔离的数据库连接与事务

定义一个数据库连接,每个线程拿到的数据库连接都是本线程对应的数据库连接。

public class ConnectionManager {

    private static final ThreadLocal<Connection> dbConnectionLocal = new ThreadLocal<Connection>() {
        @Override
        //初始化数据。
        //延迟调用方法,在线程第一次调用get或set时才执行,并且只执行1次。默认返回null。
        protected Connection initialValue() {
            try {
                return DriverManager.getConnection();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return null;
        }
    };

    public Connection getConnection() {
        return dbConnectionLocal.get();
    }
}

2.2 线程隔离的session会话

在每个线程session会话都是本线程对应的session。

private static final ThreadLocal threadSession = new ThreadLocal();  
  
public static Session getSession() {  
    Session s = (Session) threadSession.get();  
    try {  
        if (s == null) {  
            s = getSessionFactory().openSession();  
            threadSession.set(s);  
        }  
    } catch (Exception ex) {  
    }  
    return s;  
}  

总结

具体可以参考《JAVA多线程基础篇 8、线程隔离与ThreadLocal》

多线程系列在github上有一个开源项目,主要是本系列博客的实验代码。

https://github.com/forestnlp/concurrentlab

如果您对软件开发、机器学习、深度学习有兴趣请关注本博客,将持续推出Java、软件架构、深度学习相关专栏。

您的支持是对我最大的鼓励。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悟空学编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值