gpt4 book ai didi

java - jdbc 驱动程序注销后停止/中断线程

转载 作者:行者123 更新时间:2023-12-01 12:05:53 25 4
gpt4 key购买 nike

我想在 jdbc 驱动程序注销后通过调用方法来关闭线程。

public class CleanupContextListener implements ServletContextListener{
boolean driverDeregisterFlag = false;

public void contextInitialized(ServletContextEvent servletContextEvent) {
//To change body of implemented methods use File | Settings | File Templates.
}

public void contextDestroyed(ServletContextEvent servletContextEvent) {
Enumeration<Driver> drivers = DriverManager.getDrivers();
while(drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
ClassLoader driverClassLoader = driver.getClass().getClassLoader();
ClassLoader thisClassLoader = this.getClass().getClassLoader();
if (driverClassLoader != null && thisClassLoader != null && driverClassLoader.equals(thisClassLoader)) {
try {
DriverManager.deregisterDriver(driver);
driverDeregisterFlag = true;
} catch (SQLException e) {
e.printStackTrace();
}
}
}
if (driverDeregisterFlag) {
ConfigManager.stopCurrentThread();
}
}
}

如您所见,我正在尝试调用 ConfigManager.stopCurrentThread() 并停止当前线程。ConfigManager是一个实现Runnable的类。stopCurrentThread(),在ConfigManager中被定义为空方法。
我想在 stopCurrentThread() 中放入一些代码并从 ConfigManager 关闭线程。

我怎样才能做到这一点?

最佳答案

这是我的代码片段,它正在解决类似的问题。在 c3p0 池 + tomcat 8 上进行了测试,但您可能能够根据需要对其进行修改。

/**
* Destroying application context. We need to safely stop exporting thread
* and do cleanup.
*
* @param arg0
* reason for cleanup
*/
@Override
public void contextDestroyed(@NotNull ServletContextEvent arg0) {

// Safely stop exporting service and shut down the application context
super.contextDestroyed(arg0);

// Close all JDBC connections
C3P0Registry.getNumPooledDataSources();
Iterator<?> it = C3P0Registry.getPooledDataSources().iterator();
while (it.hasNext()) {
try {
PooledDataSource dataSource = (PooledDataSource) it.next();
dataSource.close();
} catch (Exception e) {
log.error("Error when closing connections ...", e);
}
}

// This manually unregisters JDBC drivers, which prevents Tomcat 7 from
// complaining about memory leaks with this class
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
try {
DriverManager.deregisterDriver(driver);
log.info(String.format("Unregistering jdbc driver: %s", driver));
} catch (SQLException e) {
log.error(
String.format("Error deregistering driver %s", driver),
e);
}
}

// Waiting for daemon close() c3p0 jdbc pool thread
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for (Thread th : threadSet) {
if (th.isDaemon()) {
try {
if (th.getName().equals(
"Resource Destroyer in BasicResourcePool.close()")) {
th.join();
}
} catch (Exception ex) {
log.info("Shutdown waiting was interrupted ...");
}
}
}
// Clear all thread local variables, this prevents Tomcat 7 from
// complaining about memory leaks
immolate();

}

/**
* Cleanup function which cleans all thread local variables. Using thread
* local variables is not a good practice but unfortunately some libraries
* are still using them. We need to clean them up to prevent memory leaks.
*
* @return number of Thread local variables
*/
private int immolate() {
int count = 0;
try {
final Field threadLocalsField = Thread.class
.getDeclaredField("threadLocals");
threadLocalsField.setAccessible(true);
final Field inheritableThreadLocalsField = Thread.class
.getDeclaredField("inheritableThreadLocals");
inheritableThreadLocalsField.setAccessible(true);
for (final Thread thread : Thread.getAllStackTraces().keySet()) {
count += clear(threadLocalsField.get(thread));
count += clear(inheritableThreadLocalsField.get(thread));
}
log.info("Immolated " + count + " values in ThreadLocals");
} catch (Exception e) {
log.error("ThreadLocalImmolater.immolate()", e);
}
return count;
}

/**
* Cleaner for thread local map.
*
* @param threadLocalMap
* thread local map to clean or null
* @return number of cleaned objects
* @throws Exception
* in case of error
*/
private int clear(@NotNull final Object threadLocalMap) throws Exception {
if (threadLocalMap == null) {
return 0;
}
int count = 0;
final Field tableField = threadLocalMap.getClass().getDeclaredField(
"table");
tableField.setAccessible(true);
final Object table = tableField.get(threadLocalMap);
for (int i = 0, length = Array.getLength(table); i < length; ++i) {
final Object entry = Array.get(table, i);
if (entry != null) {
final Object threadLocal = ((WeakReference<?>) entry).get();
if (threadLocal != null) {
log(i, threadLocal);
Array.set(table, i, null);
++count;
}
}
}
return count;
}

关于java - jdbc 驱动程序注销后停止/中断线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27604101/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com