JavaWEB-(九)ThreadLocal在JDBC中的应用

本文最后更新于:December 3, 2021 pm

ThreadLocal翻译成中文应该是:线程局部变量。ThreadLocal是一个线程内部的存储类,可以在指定线程内存储数据,数据存储以后,只有指定线程可以得到存储数据。提供了线程内存储变量的能力,这些变量不同之处在于每一个线程读取的变量是对应的互相独立的。通过get和set方法就可以得到当前线程对应的值。
在并发编程的时候,成员变量如果不做任何处理其实是线程不安全的,各个线程都在操作同一个变量,显然是不行的,并且也知道volatile这个关键字也是不能保证线程安全的。那么在有一种情况之下,需要满足这样一个条件:变量是同一个,但是每个线程都使用同一个初始值,也就是使用同一个变量的一个新的副本。这种情况之下ThreadLocal就非常使用,比如说DAO的数据库连接,知道DAO是单例的,那么他的属性Connection就不是一个线程安全的变量。而每个线程都需要使用他,并且各自使用各自的。这种情况,ThreadLocal就比较好的解决了这个问题。
当很多线程需要多次使用同一个对象,并且需要该对象具有相同初始化值的时候最适合使用ThreadLocal。

目录

在连接数据库的工具类中需要添加(修改)以下代码即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private static ThreadLocal<Connection> tl = new ThreadLocal<>();//为线程创建了一个共享对象,用来共享的是 Connection

public static Connection getConnection(){
Connection connection = tl.get();//将开始的null修改为了tl.get() 。将当前线程中绑定的Connection对象,取一个赋值给connection,第一次得到的为空,因为tl中还没有添加。但后面再次用时,就会得到上一次创建存的。
try {
if(connection == null){ //用来判断是否是首次创建
connection = DriverManager.getConnection(pr.getProperty("url"),pr.getProperty("user"),pr.getProperty("password"));
tl.set(connection);//将连接存在当前线程中共享
}
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}

完整更新后的连接数据库工具类代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package com.tothefor.Utils;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

/**
* @Author DragonOne
* @Date 2021/8/14 14:52
*/
public class MoreMove {
private static final Properties pr = new Properties();
private static ThreadLocal<Connection> tl = new ThreadLocal<>();//为线程创建了一个共享对象,用来共享的是 Connection

static {
InputStream is = MoreMove.class.getResourceAsStream("/db.properties");
try {
pr.load(is);
Class.forName(pr.getProperty("driver"));
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}

public static Connection getConnection(){
Connection connection = tl.get();
try {
if(connection == null){
connection = DriverManager.getConnection(pr.getProperty("url"),pr.getProperty("user"),pr.getProperty("password"));
tl.set(connection);
}
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}

public static void closeAll(Connection connection, Statement statement, ResultSet resultSet){
try {
if(resultSet != null){
resultSet.close();
}
if(statement != null){
statement.close();
}
if(connection != null){
connection.close();
}
}catch (SQLException e){
e.printStackTrace();
}
}

}