1.ThreadLocal是java中所提供的线程本地存储机制,可以利用该机制将数据缓存在某个线程内部,该线程可以在任意时刻、任意方法中获取缓存的数据
2.ThreadLocal底层是通过ThreadLocalMap来实现的,每个Thread对象注意不是ThreadLocal对象)中都存在一个ThreadLocalMap,Map的key为ThreadLocal对象,Map的value为需要缓存的值
3.如果在线程池中使用ThreadLocal会造成内存泄漏,因为当ThreadLoc对象使用完之后,应该要把设置的key,value,也就是Entry对象进行回收,但线程池中的线程不会回收,而线程对象是通过强引用指向ThredLocalMap,ThreadLocalMap也是通过强引用指向Entry对象,线程不被回收,Entry对象也就不会被回收,从而出现内存泄漏,解决办法是,在使用了ThreadLocal对象之后,手动调用ThreadLocal的remove方法,手动清楚Entry对象
4.ThreadLocal经典的应用场景就是连接管理(一个线程持有一个连接,该连接对象可以在不同的方法之间进行传递,线程之间不共享同一个连接)
示例:
定义一个独立的类继承 ThreadLocal
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class ConnectionThreadLocal extends ThreadLocal<Connection> {
@Override
protected Connection initialValue() {
try {
return DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password");
} catch (SQLException e) {
throw new RuntimeException("Failed to create connection", e);
}
}
}
在 ConnectionManager
中使用这个类
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class ConnectionManager {
private static final ThreadLocal<Connection> connectionHolder = new ConnectionThreadLocal();
public static Connection getConnection() {
return connectionHolder.get();
}
public static void closeConnection() {
Connection connection = connectionHolder.get();
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
connectionHolder.remove();
}
}
}
}
使用 ConnectionManager
进行数据库操作
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DatabaseService {
public void executeQuery(String sql) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = ConnectionManager.getConnection();
statement = connection.prepareStatement(sql);
resultSet = statement.executeQuery();
while (resultSet.next()) {
// Process the result set
System.out.println("Result: " + resultSet.getString(1));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// Close resources
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
// Close connection
ConnectionManager.closeConnection();
}
}
}
调用 DatabaseService
方法
public class Main {
public static void main(String[] args) {
DatabaseService service = new DatabaseService();
service.executeQuery("SELECT * FROM my_table");
}
}