使用线程本地数据库连接时,线程存在时需要关闭连接.
这只能我可以覆盖调用线程的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()).实际上它很快发生,但这并不理想. …
考虑一个BlockingQueue和几个线程等待poll(long, TimeUnit)(可能还在上take()).
现在队列是空的,并且希望通知等待的线程他们可以停止等待.预期的行为是null返回或声明InterruptedException抛出.
Object.notify()LinkedBlockingQueue因为线程正在等待内部锁定而无法工作.
有任何直截了当的方式吗?
假设我们有一个Class对象.说出来cls.
现在cls.isEnum()回来了true
真高兴!!! 我可以把价值列在我面前吗?(一个糖,没有牛奶)
以前存储的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) 我正在使用该方法
javax.xml.bind.Unmarshaller.unmarshal(Source source, Class<RX> declaredType)
Run Code Online (Sandbox Code Playgroud)
并且想知道这个方法是否是线程安全的。否则我将不得不在每次调用时实例化一个解组器
java ×3
class ×1
concurrency ×1
cursor ×1
enums ×1
jaxb ×1
soap ×1
sql ×1
sql-server ×1
thread-local ×1