我有一个限制用户一次下载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