Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 线程中断异常,释放信号量资源_Java_Multithreading_Thread Safety - Fatal编程技术网

Java 线程中断异常,释放信号量资源

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

我有三个线程,它们需要一些资源来运行我使用信号量实现的(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.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块中,如果没有,则它不起作用。为什么?