ThreadLocal

2022-12-12 17:29:28 +08:00
 gao6rich

请问 Java 中为什么一个数据库的 Connection 放到 ThreadLocal 里面复制出来多个副本在多线程中使用的话,可以互相不影响的用,实际上跟数据库不是还是只有一个连接吗?如果多线程不是同一个连接的话,跟不使用 ThreadLocal ,每个线程新建一个 connection 有什么区别呢[发呆]

2362 次点击
所在节点    Java
13 条回复
7911364440
2022-12-12 17:32:21 +08:00
贴下代码?
ajaxgoldfish
2022-12-12 17:35:57 +08:00
个人看法,主要用于传值,比如 Controler 层处理过后还需要给 mapper 层这种情景
optional
2022-12-12 17:47:56 +08:00
这样连接数不就和线程数量绑定了,对于连接数有限的数据库实例不是很尴尬,比如 pg
chendy
2022-12-12 17:50:43 +08:00
一个线程一个连接
做声明式的事务控制之类的比较方便
wolfie
2022-12-12 18:19:34 +08:00
看得一堆问号。

去看看数据库连接池。
gao6rich
2022-12-12 19:17:59 +08:00
class ConnectionManager {
private Connection connect = null;

public Connection openConnection() {
if (connect == null) {
connect = DriverManager.getConnection();
}
return connect;
}

public void closeConnection() {
if (connect != null)
connect.close();
}
}

class Dao {
public void insert() {
ConnectionManager connectionManager = new ConnectionManager();
Connection connection = connectionManager.openConnection();

// 使用 connection 进行操作

connectionManager.closeConnection();
}
}
===========================================使用 ThreadLocal

public class ConnectionManager {

private static final ThreadLocal<Connection> dbConnectionLocal = new ThreadLocal<Connection>() {
@Override
protected Connection initialValue() {
try {
return DriverManager.getConnection("", "", "");
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
};

public Connection getConnection() {
return dbConnectionLocal.get();
}
}
===========================================不使用 ThreadLocal

这两者有什么区别呢
franpinx2
2022-12-12 19:35:35 +08:00
你这样没什么区别 主要看 DriverManager.getConnection()这个方法是怎么实现的
franpinx2
2022-12-12 19:40:18 +08:00
@gao6rich 看了下 这个方法的底层没有做池化 所以你每次都会建立一个新的数据库连接 是个不推荐的写法
kaneg
2022-12-12 19:51:29 +08:00
数据库的连接可是很宝贵的资源,而线程池里的线程尽管不是毫无价值,但比起数据库的连接来说便宜很多。所以,当某个线程需要数据库连接的时候,就从连接池中拿一个,用完立即释放以便别的线程可以申请到。
boatrain1111
2022-12-12 19:54:19 +08:00
用的是同一个 tcp 连接吧
CRVV
2022-12-12 23:29:12 +08:00
thread-local 是指每个线程都有自己的变量。虽然代码里面是同一个变量,但每个线程用的是各自的变量。
所以每个线程里面用的是不同的 connection 。数据库连接和线程数一样多。


> 如果多线程不是同一个连接的话,跟不使用 ThreadLocal ,每个线程新建一个 connection 有什么区别呢

如果每个线程新建一个连接,用完就关下次再重连,那就没有区别。
如果要把连接留着以后再用,就需要一个地方存着这个 connection ,下次再用的时候每个线程每次都能拿到当前线程的 connection 。当然可以自己实现这一套东西,实现好了你就重写了 thread-local
lyusantu
2022-12-13 09:26:37 +08:00
ThreadLocal 允许线程之间共享数据库连接
byte10
2022-12-14 10:09:36 +08:00
17 楼 表达正确,ThreadLocal 主要是就是传递开启事务中的 mysql 链接。同一个事务,连接是同一个的。如果没有事务的话,你同一个线程得到的 mysql 连接都可能不一样。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/902004

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX