小编Joe*_*tov的帖子

如何强制Java线程关闭线程本地数据库连接

使用线程本地数据库连接时,线程存在时需要关闭连接.

这只能我可以覆盖调用线程的run()方法.即使这不是一个很好的解决方案,因为在退出时,我不知道该线程是否曾打开过连接.

问题实际上更为通用:如何强制线程在线程局部对象退出时调用某些终结方法.

我查看了java 1.5的源代码,发现线程本地映射设置为null,这最终会导致垃圾收集调用finalize(),但我不想指望垃圾收集器.

以下覆盖似乎是不可避免的,以确保关闭数据库连接:

@Override 
public void remove() {
    get().release(); 
    super.remove(); 
}
Run Code Online (Sandbox Code Playgroud)

其中,release()关闭数据库连接(如果已打开).但我们不知道线程是否曾使用过本地线程.如果此线程从未调用过get(),那么这里的工作就相当浪费:将调用ThreadLocal.initialValue(),在此线程上创建一个map等.

-

根据Thorbjørn的评论进一步澄清和举例:

java.lang.ThreadLocal是绑定到线程的对象的工厂类型.此类型具有对象的getter和工厂方法(通常由用户编写).当调用getter时,只有在此线程之前从未调用过它时才调用工厂方法.

使用ThreadLocal允许开发人员将资源绑定到线程,即使线程代码是由第三方编写的.

示例:假设我们有一个名为MyType的资源类型,我们希望每个线程只有一个.

在using类中定义:private static ThreadLocal resourceFactory = new ThreadLocal(){@ override protected MyType initialValue(){return new MyType(); }}

在此类的本地上下文中使用:public void someMethod(){MyType resource = resourceFactory.get(); resource.useResource(); }

get()只能在调用线程的生命周期中调用initialValue()一次.此时,MyType的实例将被实例化并绑定到此线程.此线程对get()的后续调用再次引用此对象.

经典用法示例是MyType是一些线程不安全的text/date/xml格式化程序.

但是这样的格式化程序通常不需要被释放或关闭,数据库连接也是如此,我使用java.lang.ThreadLocal来为每个线程建立一个数据库连接.

我看待它的方式,java.lang.ThreadLocal几乎是完美的.几乎是因为如果调用线程属于第三方应用程序,则无法保证资源的关闭.

我需要你的大脑绅士:通过扩展java.lang.ThreadLocal,我设法为每个线程绑定一个数据库连接,因为它的独占用途 - 包括我无法修改或覆盖的线程.我设法确保在线程因未捕获的异常而死的情况下关闭连接.

在正常线程退出的情况下,垃圾收集器关闭连接(因为MyType会覆盖finalize()).实际上它很快发生,但这并不理想. …

java thread-local resource-disposal

13
推荐指数
2
解决办法
8800
查看次数

如何立即释放在BlockingQueue上等待的线程

考虑一个BlockingQueue和几个线程等待poll(long, TimeUnit)(可能还在上take()).

现在队列是空的,并且希望通知等待的线程他们可以停止等待.预期的行为是null返回或声明InterruptedException抛出.

Object.notify()LinkedBlockingQueue因为线程正在等待内部锁定而无法工作.

有任何直截了当的方式吗?

java concurrency blockingqueue

9
推荐指数
2
解决办法
7579
查看次数

列出未知枚举的值

假设我们有一个Class对象.说出来cls.

现在cls.isEnum()回来了true

真高兴!!! 我可以把价值列在我面前吗?(一个糖,没有牛奶)

java enums class

8
推荐指数
1
解决办法
2222
查看次数

游标和存储过程优化

以前存储的proc已经写了一段时间,现在需要修改.

无法联系原始开发人员,我看了一下.对我来说,这个过程似乎过于复杂.难道不能通过简单的UPDATE完成吗?任何人都可以在这里证明使用CURSOR吗?

ALTER PROCEDURE [settle_Stage1]
    @settleBatch int
AS

DECLARE @refDate datetime;
DECLARE @dd int;
DECLARE @uid int;

DECLARE trans_cursor CURSOR FOR 
SELECT uid, refDate FROM tblTransactions WHERE (settle IS NULL ) AND (state IN (  21, 31, 98, 99 ))
OPEN trans_cursor
FETCH FROM trans_cursor INTO @uid, @refDate
WHILE @@FETCH_STATUS = 0
   BEGIN
    SET @dd = DATEDIFF( day, @refDate, getDate())
    IF ( @dd >= '1' )
      BEGIN
        UPDATE tblTransactions
        SET settle = @settleBatch WHERE uid = @uid
      END
    FETCH FROM …
Run Code Online (Sandbox Code Playgroud)

sql sql-server stored-procedures cursor query-optimization

3
推荐指数
1
解决办法
323
查看次数

解组线程安全吗?

我正在使用该方法

javax.xml.bind.Unmarshaller.unmarshal(Source source, Class<RX> declaredType) 
Run Code Online (Sandbox Code Playgroud)

并且想知道这个方法是否是线程安全的。否则我将不得不在每次调用时实例化一个解组器

soap jaxb thread-safety

3
推荐指数
1
解决办法
1120
查看次数