사용자가 한 번에 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!!!
이
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의 스택 트레이스는 왜 스레드 4하지 예외를받을 않습니다입니까?
이이 문제에 도움이되지 않습니다,하지만 당신은이 할 필요가있는 경우에는 세마포어 누출이 없도록는, 최종적으로 블록에 "해제"를 호출 놓아야 대신
같은 것을 시도 예외는 다운로드 중입니다. – Thilo
세 번째로 중단하면 어떻게됩니까? "획득"을 기다리고 있습니까? 그걸 확인하기 위해 JVM 스레드 덤프 (kill -QUIT)를 얻을 수 있습니까? – Thilo
새로운 스레드는 모두 획득시 대기 상태를 유지하고이 상태에 도달하면 중단 될 수 없습니다. 이제 원래의 쓰레드 1과 쓰레드 2가 실행을 끝내고 세마포어를 릴리즈하더라도 새로운 쓰레드는 acquire()를 무한정 기다리게된다 !! 질문에 스택 추적을 추가했습니다. – Prashast