解锁锁定同步块的可靠方法



偶尔系统会在同步块上抛出严重错误,并且有一个try-catch,理论上应该启动线程"解锁"过程,但这并没有触发。I、 因此,可以得出结论,这在系统内不被视为例外。是否有合理的方法来处理上述锁?

考虑来自board.jsp的以下代码:

account = Account.get(accountID);
Object synch=account;
if(synch == null) {
%>No account.<%
return;
}
try {
synchronized(synch) {
....
}
} catch (Exception e) {
....
} finally {
....
}

示例转储

SEVERE: Scheduled tasks not running!
Apr 07, 2020 4:59:36 PM ExecLauncher:execLauncher run
SEVERE: ---------------------
Thread is: "http-bio-8080-exec-18" Id=122 BLOCKED on com.main.Account@5a0b8133 owned by "http-bio-8080-exec-7" Id=38
at org.apache.jsp.realtime.board_jsp._jspService(board_jsp.java:192)
-  blocked on com.main.Account@5a0b8133
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)

感谢您的关注:(

您可以尝试一下,使用Reentrant锁可以获得更多的锁定和解锁控制。

account = Account.get(accountID);
Object synch=account;
Lock lock = new ReentrantLock();

if(synch == null) {
%>No account.<%
return;
}
try {
lock.lock();
/* Your actual code which you were executing in 
the synchronized block */
} catch (Exception e) {
....
} finally {
lock.unlock(); // this will work
}

这不是一个例外,而是说线程"http-bio-8080-exec-18"无法执行,因为它试图进入synchronized(synch(块。它无法进入此块,因为监视器当前由线程"http-bio-8080-exec-7"持有。

因此,第一件事就是找出"http-bio-8080-exec-7"不发布监视器的原因。这可能只是一个性能问题,因为许多线程都试图并行执行tissection。或者这根线可能是挂着的。您可以通过生成线程转储进行分析:

要生成线程转储,请转到java安装的bin文件夹。有一个名为jps(windows上的jps.exe(的工具执行此操作,您将看到一个数字(pid(和一个程序的名称。找到您的程序并执行jstack[pid]。jstack也在Java安装的bin文件夹中。

然后,您将看到程序中的每个线程都在做什么,以及拥有监视器的线程正在做什么。

有一种方法可以只等待特定的时间来尝试解锁锁。我不太确定这是否能解决你的问题,但为了完整起见,它就在这里。将可重入锁与tryLock:一起使用

if( lock.tryLock(long timeout,
TimeUnit unit))
{ try {
// ... method body
} 
finally {
lock.unlock()
} 
}
else {
// lock could not be acquired at the given time
}

最新更新