什么是“线程封闭”?

为了确保线程的安全,通常需要保证可变的共享数据的同步访问,具体采用的方式有很多;但还有一种方法可以保证线程的安全,即是使可变数据不共享,或者是使数据不可变。所谓“线程封闭”即是仅在单线程中访问数据,也就是通过让可变数据不被多个线程共享以确保数据的正确性。

栈封闭

局部变量在函数的作用域当中,只有该函数本身可以访问,因此,也就自然地保证了线程的安全性。这就是线程封闭中的“栈封闭”。举例如下所示。

public int Test(int count){
    int number = 0;
    for(int i = 0; i < count; i++){
        ++number;
    }
    return number;
}

以上示例代码中的number就是一个栈封闭的变量,因为是Test函数的局部变量,因此该变量被封闭在单线程中,无需使用其他线程安全的关键字或方法,Java的语义天然地维护了其正确性。

ThreadLocal类

维持线程封闭性的一种更规范方法是使用ThreadLocal。这个类提供了ThreadLocal.get()、ThreadLocal.set()、ThreadLocal.initialValue()。initialValue()用于为ThreadLocal对象的共享变量赋予一个初始值,set()用于为ThreadLocal对象的共享变量赋值,get()用于获取ThreadLocal对象的共享变量。ThreadLocal对象的共享变量被封闭在对象内,只能被该对象操作。

ThreadLocal对象通常用于防止可变的单实例变量或全局变量进行共享。例如:在单线程应用程序中可能会维持一个全局的数据库连接,并在程序启动时初始化这个连接对象,从而避免在调用每个方法时都要传递一个Connection对象。由于JDBC的连接对象不一定是线程安全的,因此,当多线程程序在没有协同的情况下使用全局变量时,就不是线程安全的。通过将JDBC的连接保存到ThreadLocal对象中,每个线程都会拥有属于自己的连接,如下为代码示例。

private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>(){
    //初始化ThreadLocal对象connectionHolder的共享变量为Connection类型的对象
    public Connection initialValue(){
        return DriverManager.getConnection(DB_URL);  
    }
};

public static Connection getConnection(){
    //使用ThreadLocal对象的get()方法获取其共享变量
    return connectionHolder.get();
}

 

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值