如何强制Java线程关闭线程本地数据库连接
当使用线程本地数据库连接时,线程存在时需要关闭连接.
我只能在覆盖调用线程的run()方法的情况下才能做到这一点.即使这不是一个很好的解决方案,因为在退出时,我不知道连接是否曾被该线程打开. 问题其实是一般的:如何强制线程在线程本地对象退出时调用一些finalization方法. 我查看了java 1.5的源码,发现线程本地地图设置为null,最终会导致垃圾回收调用finalize(),但我不想指望垃圾收集器. 以下重写似乎是不可避免的,以确保数据库连接已关闭: @Override public void remove() { get().release(); super.remove(); } 其中release()关闭数据库连接,如果已经打开.但是我们不知道线程是否曾经使用过这个线程本地的.如果这个线程没有调用get(),那么在这里将耗费很多精力:ThreadLocal.initialValue()将被调用,这个线程上将创建一个map. – 根据Thorbj?rn的评论进一步澄清和举例: java.lang.ThreadLocal是绑定到线程的对象的一种工厂类型.此类型具有对象的getter和工厂方法(通常由用户编写).当getter被调用时,它调用factory方法,只有当它从未被这个线程调用过. 使用ThreadLocal允许开发人员将资源绑定到线程,即使线程代码是由第三方编写的. 例: 在使用类中定义: 在本课程中使用本地上下文: get()可以在调用线程的生命周期中调用initialValue()一次.此时,MyType的实例被实例化并绑定到此线程.随后通过此线程调用get()再次引用此对象. 经典使用示例是当MyType是一些线程不安全的文本/日期/ xml格式化程序时. 但是,这样的格式化程序通常不需要被释放或关闭,数据库连接和我正在使用java.lang.ThreadLocal每个线程都有一个数据库连接. 我看到它的方式,java.lang.ThreadLocal几乎是完美的.几乎因为如果调用线程属于第三方应用程序,则无法保证资源的关闭. 我需要你的脑筋:通过扩展java.lang.ThreadLocal我设法为每个线程绑定一个数据库连接,因为它是独占使用 – 包括我无法修改或覆盖的线程.我设法确保连接关闭,以防线程在未捕获的异常情况下死亡. 在正常线程退出的情况下,垃圾回收器关闭连接(因为MyType覆盖finalize()).实际上它发生得很快,但这并不理想. 如果我有我的方式,那么在java.lang.ThreadLocal中会有另一种方法: protected void release() throws Throwable {} 如果这个方法存在于java.lang.ThreadLocal,在任何线程退出/死亡时由JVM调用,然后在我自己的覆盖中,我可以关闭我的连接(救赎者将来到锡安). 在没有这种方法的情况下,我正在寻找另一种方式来确认关闭.一种不依赖于JVM垃圾收集的方式. 谢谢 解决方法
如果你是一个敏感的处置,现在看看.
我不会指望这个比例很好;它有效地使系统中的线程数增加了一倍.可能有一些可以接受的用例. public class Estragon { public static class Vladimir { Vladimir() { System.out.println("Open"); } public void close() { System.out.println("Close");} } private static ThreadLocal<Vladimir> HOLDER = new ThreadLocal<Vladimir>() { @Override protected Vladimir initialValue() { return createResource(); } }; private static Vladimir createResource() { final Vladimir resource = new Vladimir(); final Thread godot = Thread.currentThread(); new Thread() { @Override public void run() { try { godot.join(); } catch (InterruptedException e) { // thread dying; ignore } finally { resource.close(); } } }.start(); return resource; } public static Vladimir getResource() { return HOLDER.get(); } } 更好的错误处理等作为实施者的练习. 您还可以查看跟踪线程/资源的ConcurrentHashMap与另一个线程轮询isAlive.但是解决方案是绝望的最后手段 – 对象可能最终被检查太频繁或太少. 我不能想到任何不涉及仪器的事情. AOP可能工作. 连接池将是我最喜欢的选择. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |