2012-08-24 27 views
8

Từ tài liệu Java java.util.concurrent.Semaphore nó không hoàn toàn rõ ràng với tôi điều gì sẽ xảy ra nếu semaphore.acquire() khóa luồng và sau đó bị gián đoạn bởi một InterruptedException. Có giá trị semaphore đã được giảm và như vậy là có cần phải phát hành semaphore?Cần phải semaphore.relase() nếu semaphore.acquire() được InterruptedException?

Hiện nay tôi đang sử dụng mã như thế này:

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

Hoặc tôi nên thay không gọi phóng thích() khi một InterruptedException xảy ra trong quá Acquire()?

Trả lời

8

phát hành cuộc gọi() khi xảy ra gián đoạn gián đoạn trong quá trình mua()?

Bạn không nên. Nếu .acquire() bị gián đoạn, semaphore không được mua lại, vì vậy có khả năng không nên phát hành nó.

Mã của bạn nên

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

Cảm ơn, điều đó rất hợp lý. Tôi sẽ thay đổi mã của tôi như bạn đã đề xuất. – kasimir

+5

Vấn đề với điều này là semaphore.acquire() cũng ném InterruptedException. – jblack

0

Nếu thread bị gián đoạn trước khi gọi phương thức có được, hoặc trong khi chờ đợi để có được một giấy phép các InterruptedException sẽ được ném ra và không có giấy phép sẽ được tổ chức, vì vậy không cần thiết phải phát hành. Chỉ khi bạn chắc chắn rằng một giấy phép đã được mua lại (sau khi gọi phương thức nhận cuộc gọi), bạn sẽ cần phải phát hành giấy phép. Vì vậy, bạn có được tốt hơn trước khi bắt đầu khối try của bạn, một cái gì đó như:

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

của nos chấp nhận câu trả lời là một phần đúng, ngoại trừ semaphore.acquire() cũng ném InterruptedException. Vì vậy, để chính xác 100%, mã sẽ trông giống như:

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

Có thực sự cần thiết để bắt lồng nhau không? Chúng ta có thể có được và phát hành semaphore chỉ trong một thử bắt? – Joyce

+2

Giả sử bạn muốn xử lý các trường hợp một cách duyên dáng khi cuộc gọi đến semaphore.acquire() ném một InterruptedException, các lệnh try-catch lồng nhau là cần thiết. InterruptedException có thể được ném cả trong suốt cuộc gọi đến semaphore.acquire() và sau khi nó đã được mua lại. http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html#acquire() – jblack

+0

Có ổn không nếu tôi sử dụng trường hợp ngoại lệ 'Ngoại lệ 'thay vì' InterruptedException e '? – Joyce