Java 线程中断异常,释放信号量资源
我有三个线程,它们需要一些资源来运行我使用信号量实现的(A、B、C)Java 线程中断异常,释放信号量资源,java,multithreading,thread-safety,Java,Multithreading,Thread Safety,我有三个线程,它们需要一些资源来运行我使用信号量实现的(A、B、C) public void run(){ while(!Thread.currentThread().isInterrupted){ try{ A.acquire(2); B.acquire(2); //some-stuff } catch(InterruptedException ex){} finally{ A.release(2); //PROBLEM B.re
public void run(){
while(!Thread.currentThread().isInterrupted){
try{
A.acquire(2);
B.acquire(2);
//some-stuff
}
catch(InterruptedException ex){}
finally{
A.release(2); //PROBLEM
B.release(2);
}
}
问题:在运行时,线程可能会被中断,但是,在finally
方法中,我不知道在中断期间我在哪里,所以我不知道是否必须释放某些内容。
我尝试了很多不同的实现,比如使用方法(boolean)tryAcquire()
,但是出现了另一个问题:如果我得到了资源a而不是B,那么在finally块中,我会再次释放a等等。
你有什么建议吗?谢谢。使用嵌套的
尝试块:
try {
A.acquire(2);
try {
B.acquire(2);
try {
// some stuff
} finally {
B.release(2);
}
} finally {
A.release(2);
}
} catch (InterruptedException ex) {}
您可以尝试像这样使用List
:
List<Semaphore> acquired = new ArrayList<>(2);
while(!Thread.currentThread().isInterrupted) {
try{
A.acquire(2);
acquired.add(A);
B.acquire(2);
acquired.add(B);
//some-stuff
} catch(InterruptedException ex){}
finally{
for (Semaphore s : acquired) {
s.release(2);
}
s.clear();
}
}
获取的列表=新的ArrayList(2);
而(!Thread.currentThread().isInterrupted){
试一试{
A.获得(2);
添加(A);
B.获得(2);
添加(B);
//一些东西
}catch(InterruptedException ex){}
最后{
for(信号量s:已获取){
s、 释放(2);
}
s、 清除();
}
}
我认为问题的核心是“原子陈述”。在您的示例中,如果A.acquire(2)和acquired.add(A)之间发生中断,该怎么办?在finally block 2中,A的资源不会被释放。@alessandroAmedei如果中断发生在A.acquire(2)
上,则将抛出异常,并且finally
将正确执行(未获取任何内容,未释放任何内容)。但如果线程在acquire
和acquired.add()
之间中断,则不会引发异常,程序将继续执行,并将向列表中添加资源谢谢!这样行吗code public void run(){while(!Thread.currentThread().isInterrupted()){boolean a=false;boolean b=false;try{Main.a.acquire(2);a=true;Main.b.acquire(2);b=true;buffer.setAB(value);value++;Thread.sleep(1000);}catch(InterruptedException ex){}最后{if(a){Main.a.release(2);}if(b){Main.b.release(2);}}}}}
@alessandroAmedei我想是的。您还可以为代码编写单元测试,用于正常执行和InterruptedException
case我必须添加code-Thread.currentThread().interrupt()代码>在catch块中,如果没有,则它不起作用。为什么?