2012-08-24 8 views
8

Z dokumentacji Java java.util.concurrent.Semaphore nie było dla mnie jasne, co się stanie, jeśli semafore.acquire() blokuje wątek, a później zostaje przerwany przez wyjątek InterruptedException. Czy wartość semafora została zmniejszona i czy istnieje potrzeba zwolnienia semafora?Potrzebujesz do semafore.relase() czy semaphore.acquire() dostaje wyjątek InterruptedException?

Obecnie używam kodu:

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

lub nie powinny raczej wywołać uwolnienie(), gdy wystąpi InterruptedException podczas nabywać()?

Odpowiedz

8

wywołanie połączenia(), gdy wystąpi wyjątek InterruptedException podczas nabywania()?

Nie powinieneś. Jeśli .acquire() zostanie przerwane, semafor nie zostanie pozyskany, więc prawdopodobnie nie powinien go zwolnić.

Kod powinien być

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

Dzięki, to brzmi bardzo rozsądnie. Zmienię kod, tak jak sugerowałeś. – kasimir

+5

Problem polega na tym, że semafore.acquire() również generuje wyjątek InterruptedException. – jblack

0

Jeśli nić zostanie przerwany przed metoda nabyć połączenia lub podczas oczekiwania na uzyskanie pozwoleniu InterruptedException zostanie wyrzucony i nie pozwolenie będzie trzymać, więc nie ma potrzeby, aby zwolnić. Tylko wtedy, gdy masz pewność, że pozwolenie zostało nabyte (po wywołaniu metody nabycia), musisz zwolnić zezwolenie. Więc lepiej nabyć przed rozpoczęciem swojego bloku try, coś jak:

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

NOS zaakceptował odpowiedź jest częściowo poprawny, z wyjątkiem semaphore.acquire() rzuca również InterruptedException. Aby uzyskać 100% poprawności, kod powinien wyglądać następująco:

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

Czy naprawdę trzeba zagnieżdżać próbę catch? Czy możemy zdobyć i uwolnić semafor za jednym podejściem? – Joyce

+2

Zakładając, że chcesz sprawnie obsługiwać obudowę, gdy wywołanie metody semaphore.acquire() zgłasza wyjątek InterruptedException, wymagane są zagnieżdżone try-catch. InterruptedException może być wywoływany zarówno podczas wywołania semafore.acquire(), jak i po jego uzyskaniu. http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html#acquire() – jblack

+0

Czy mogę używać ogólnego przypadku 'Exception e' zamiast' InterruptedException e '? – Joyce

Powiązane problemy