2012-08-24 18 views
8

Aus der Java java.util.concurrent.Semaphore docs war es mir nicht ganz klar, was passiert, wenn semaphore.acquire() den Thread blockiert und später durch eine InterruptedException unterbrochen wird. Wurde der Semaphorwert verringert und muss der Semaphor freigegeben werden?Benötigen Sie semaphore.relase() wenn semaphore.acquire() InterruptedException bekommt?

Derzeit bin ich mit Code wie folgt:

try { 
    // use semaphore to limit number of parallel threads 
    semaphore.acquire(); 
    doMyWork(); 
} 
finally { 
    semaphore.release(); 
} 

Oder soll ich rufe eher nicht Release(), wenn ein InterruptedException während acquire auftritt()?

Antwort

8

Aufruf release() wenn eine InterruptedException während acquire() auftritt?

Sie sollten nicht. Wenn .acquire() unterbrochen wird, wird das Semaphor nicht erworben, also sollte es wahrscheinlich nicht freigegeben werden.

Code sollte

// use semaphore to limit number of parallel threads 
semaphore.acquire(); 
try { 
    doMyWork(); 
} 
finally { 
    semaphore.release(); 
} 
+0

Danke, das klingt sehr vernünftig. Ich werde meinen Code ändern, wie Sie es vorgeschlagen haben. – kasimir

+5

Das Problem dabei ist, dass semaphore.acquire() auch InterruptedException auslöst. – jblack

0

werden, wenn der Faden vor acquire Methodenaufruf unterbrochen wird, oder während des Wartens auf eine Genehmigung zum Erwerb der InterruptedException geworfen werden und wird keine Genehmigung halten werden, so dass keine Notwendigkeit zu lösen. Nur wenn Sie sicher sind, dass eine Genehmigung erworben wurde (nach dem Aufruf der Methode acquire), müssen Sie die Genehmigung freigeben. Also besser zu erwerben, bevor Sie Try-Block beginnt, so etwas wie:

sem.acquire(); 
try{ 
    doMyWork(); 
}finally{ 
    sem.release(); 
} 
3

nos die akzeptierte Antwort teilweise richtig ist, mit der Ausnahme semaphore.acquire() auch wirft InterruptedException. Also, um 100% korrekt zu sein, würde der Code wie folgt aussehen:

try { 
    semaphore.acquire(); 
    try { 
     doMyWork(); 
    } catch (InterruptedException e) { 
     // do something, if you wish 
    } finally { 
     semaphore.release(); 
    } 
} catch (InterruptedException e) { 
    // do something, if you wish 
} 
+0

Ist es wirklich notwendig, nested try catch zu haben? Können wir den Semaphor in nur einem Versuch fangen und freigeben? – Joyce

+2

Angenommen, Sie möchten den Fall ordnungsgemäß behandeln, wenn der Aufruf von semaphore.acquire() eine InterruptedException auslöst, sind die verschachtelten Try-Catchs erforderlich. InterruptedException kann sowohl während des Aufrufs von semaphore.acquire() als auch nach dem Abrufen ausgelöst werden. http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html#acquire() – jblack

+0

Ist es in Ordnung, wenn ich einen generischen 'Exception e' Fall anstelle von' InterruptedException e '? – Joyce