我有一個限制用戶一次下載n個文件的信號量。每個文件都在一個單獨的線程中下載。多次中斷信號量的問題
編輯:修改的例子,使得釋放正確執行
import java.util.concurrent.Semaphore;
public void downloadFile() {
Thread downloadThread = new Thread() {
boolean bSemaphoreAcquired = false;
public void run() {
try {
semaphore.acquire();
bSemaphoreAcquired = true;
// do the download
} catch (InterruptedException e) {
} finally {
if (bSemaphoreAcquired) semaphore.release();
}
}
};
// add download thread to the list of download threads
downloadThread.start();
}
現在,任何新的下載將等待前一個下載完成一次信號的所有許可證已被收購。
當用戶選擇取消正在等待獲取調用的下載時,我調用interrupt()方法來終止該下載線程。 我面臨的問題是,一旦這個信號被中斷,它不會拋出InterruptedException異常第二次!任何創建的新線程都會等待獲取方法永遠!
Sequence of events (Semaphore that permits 2 threads)
- thread 1 downloading
- thread 2 downloading
- thread 3 waiting on acquire()
- thread 3 is cancelled (interrupt() is called). InterruptedException is thrown and the thread exits
- thread 4 is created and is now waiting on acquire()
- thread 4 is cancelled (interrupt() is called). InterruptedException IS NOT THROWN ANYMORE!!!
這是線程4
Semaphore$FairSync(AbstractQueuedSynchronizer).fullGetFirstQueuedThread() line: 1276
Semaphore$FairSync(AbstractQueuedSynchronizer).getFirstQueuedThread() line: 1232
Semaphore$FairSync.tryAcquireShared(int) line: 201
Semaphore$FairSync(AbstractQueuedSynchronizer).acquireSharedInterruptibly(int) line: 1142
Semaphore.acquire() line: 267
FileDownloadManager$1.run() line: 150
的堆棧跟蹤爲什麼線程4未收到異常?
這不符合您的問題有所幫助,但你應該把「釋放」調入finally塊,所以不存在信號泄漏是否應該有一個下載時出現異常。 – Thilo 2009-08-04 08:20:41
如果第三次打斷它會怎麼樣?你確定它在等待「獲得」嗎?你能得到一個JVM線程轉儲(kill -QUIT)來確保這一點嗎? – Thilo 2009-08-04 08:35:48
所有新線程都會一直等待獲取,一旦達到此狀態就不會中斷。現在,即使原始線程1和線程2完成執行並釋放信號量,新線程仍然無限期地等待acquire()!將堆棧跟蹤添加到問題中。 – Prashast 2009-08-04 08:44:22