【发布时间】:2015-03-13 08:54:36
【问题描述】:
假设我有以下内容:
public class DAOFactory {
@Inject private final SessionFactory factory;
private final ThreadLocal<Session> session = new ThreadLocal<>();
// In a nutshell: create an AbstractDAO associated with the session object held by the ThreadLocal above
public <T> AbstractDAO<T> createObject(Class<T> objectClass) { ... }
}
我遇到的问题是这些会话需要关闭,只有从createObject() 创建 DAO 的线程才能做到这一点。显然,AbstractDAO 不能有一个关闭例程,因为同一个Session 可以与多个AbstractDAO 对象相关联,所以DAOFactory 必须承担关闭会话的负担。尽管如此,Sessions 仍然存在悬空的风险:如果创建 AbstractDAO 的线程不再存在,如何关闭关联的 Session?
我有一个方法是有一个清理方法如下:
public class DAOFactory {
// createObject() uses Thread.getCurrentThread.getId() and sessionMap.computeIfAbsent()
private final ConcurrentMap<Long, Session> sessionMap = new ConcurrentHashMap<>();
public void cleanup() {
for (Session session : sessionMap.values()) {
session.close();
}
sessionMap.clear();
}
}
问题是“这种方法有多安全”、“这是个好主意”和“应该这样做”吗?如果没有,有什么好的选择?
请注意,DAOFactory 的创建主要考虑了某种测试情况:一个线程开始测试运行并创建一个DAOFactory,它可能会产生使用它的其他线程。创建DAOFactory 的线程将始终比它产生的任何线程更持久,并且始终是在测试结束时调用cleanup() 的线程。
【问题讨论】:
标签: java multithreading hibernate session thread-safety