J'ai un sémaphore qui limite les utilisateurs à télécharger n nombre de fichiers à la fois. Chaque fichier est téléchargé dans un fil séparé.Problème dans le sémaphore étant interrompu plusieurs fois
EDIT: l'exemple modifié de sorte que la libération se produise correctement
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();
}
Maintenant, tous les nouveaux téléchargements attendront les téléchargements précédents pour terminer une fois que tous les permis de sémaphores ont été acquis.
Lorsque l'utilisateur choisit d'annuler un téléchargement en attente à l'appel d'acquisition, j'appelle la méthode interruption() pour terminer ce fil de téléchargement. Le problème auquel je suis confronté est qu'une fois que ce sémaphore a été interrompu, il ne jetterait pas l'exception InterruptedException la deuxième fois !! Tout nouveau thread créé attendra la méthode acquérir pour toujours!
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!!!
Ceci est la trace de la pile de fil 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
Pourquoi fil 4 reçoit pas l'exception?
Cela ne contribue pas à votre problème, mais vous devez mettre la « libération » appel en bloc finally, afin qu'il n'y ait pas de fuite de sémaphores si devrait y avoir un exception lors du téléchargement. – Thilo
Que se passe-t-il si vous l'interrompez une troisième fois? Êtes-vous sûr qu'il attend sur le "acquérir"? Pouvez-vous obtenir un vidage de thread JVM (kill -QUIT) pour vous en assurer? – Thilo
Tous les nouveaux threads attendent juste d'acquérir et ne peuvent pas être interrompus une fois qu'il a atteint cet état. Maintenant, même si le thread d'origine 1 et le thread 2 terminent l'exécution et libèrent le sémaphore, les nouveaux threads continuent à attendre indéfiniment sur acquire() indéfiniment !! Ajout de la trace de la pile à la question. – Prashast