0

我们正在使用 Hibernate 运行一个多类加载器 java 应用程序:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.4.16.Final</version>
</dependency>
<dependency>
    <groupId>com.oracle.database.jdbc</groupId>
    <artifactId>ojdbc10-production</artifactId>
    <version>19.7.0.0</version>
    <type>pom</type>
</dependency>

我们注意到,即使关闭了所有的 Hibernate 和工件以及unregister驱动程序,我们仍然可以看到线程保持活动状态,这些线程将类加载器保存在contextclassloader. 有没有办法关闭这些线程Timer& OracleTimeoutPollingThread

 public void close() throws IOException {
    sessionFactory.close();
    session.close();
    factory.close();

    try {
      Enumeration<Driver> de = DriverManager.getDrivers();
      while(de.hasMoreElements()) {
        Driver d = de.nextElement();
        if(d.getClass().getClassLoader() == RGHibernate.class.getClassLoader()) {
          DriverManager.deregisterDriver(d);
        }

      }
    } catch (SQLException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}

堆转储分析

4

1 回答 1

0
    protected void cancelTimers() {
        try {
            for (Thread thread : Thread.getAllStackTraces().keySet())
                if (thread.getClass().getSimpleName().equals("TimerThread"))
                    cancelTimer(thread);
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    private void cancelTimer(Thread thread) throws Exception {
        // Timer::cancel
        Object queue = ReflectionUtils.getFieldValue(thread, "queue");
        Method m = queue.getClass().getDeclaredMethod("isEmpty");
        m.setAccessible(true);
        if ((boolean) m.invoke(queue)) {
            synchronized (queue) {
                ReflectionUtils.setFieldValue(thread, "newTasksMayBeScheduled", false);
                m = queue.getClass().getDeclaredMethod("clear");
                m.setAccessible(true);
                m.invoke(queue);
                queue.notify();
            }
        }
    }
于 2020-07-01T00:10:32.707 回答