Existe-t-il un objet Mutex en java ou un moyen d'en créer un? Je demande parce qu'un objet Semaphore initialisé avec 1 permis ne m'aide pas. Pensez à ce cas:
try {
semaphore.acquire();
//do stuff
semaphore.release();
} catch (Exception e) {
semaphore.release();
}
si une exception se produit lors de la première acquisition, la libération dans le bloc catch augmentera les autorisations et le sémaphore n'est plus un sémaphore binaire.
La bonne manière sera-t-elle?
try {
semaphore.acquire();
//do stuff
} catch (Exception e) {
//exception stuff
} finally {
semaphore.release();
}
Le code ci-dessus garantira-t-il que le sémaphore sera binaire?
Réponses:
Consultez cette page: http://www.oracle.com/technetwork/articles/javase/index-140767.html
Il a un motif légèrement différent qui est (je pense) ce que vous recherchez:
Dans cet usage, vous n'appelez
release()
qu'après un succèsacquire()
la source
Tout objet en Java peut être utilisé comme verrou à l'aide d'un
synchronized
bloc. Cela prendra également en charge automatiquement la libération du verrou lorsqu'une exception se produit.Vous pouvez en savoir plus à ce sujet ici: Verrous et synchronisation intrinsèques
la source
synchronized
, vous verrez ce qui est mieux lisible et moins sujet aux erreurs.transaction.begin(); transaction.commit()
).someObject.wait(timeout)
etsomeObject.notify()
pendant que vous regardez le code de cette réponse.la source
"Lock implementations provide more extensive locking operations than can be obtained using synchronized methods and statements."
de: docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/… ... bien que vous ayez un point. La réponse d'Argv n'illustre ni n'explique ces opérations.private final ReentrantLock _mutex = ...
, vous pouvez utiliser getHoldCount () pour renvoyer le nombre de re-verrouillages de threads. (Vous pouvez appliquer unCondition
pour éviter cela. Voir l'API .)Personne ne l'a clairement mentionné, mais ce type de modèle n'est généralement pas adapté aux sémaphores. La raison est que tout thread peut libérer un sémaphores, mais vous ne voulez généralement que le thread propriétaire que verrouillé à l' origine pour pouvoir déverrouiller . Pour ce cas d'utilisation, en Java, nous utilisons généralement ReentrantLocks, qui peuvent être créés comme ceci:
Et le modèle d'utilisation habituel est:
Voici un exemple dans le code source java où vous pouvez voir ce modèle en action.
Les verrous réentrants présentent l'avantage supplémentaire de favoriser l'équité.
N'utilisez des sémaphores que si vous avez besoin d'une sémantique sans propriété.
la source
count=1
n'est pas un verrou d'exclusion mutuelle.lock
par exempleReentrantLock
unmutex
? Je ne sais pas pourquoimutex
etbinary semaphore
sont assimilés à la même entité.Semaphore
peut être libéré par n'importe quel thread, ce qui ne garantit pas la protectioncritical section
. Des pensées?Je pense que vous devriez essayer avec:
Pendant l'initialisation du sémaphore:
Et dans votre
Runnable Implementation
la source
L'erreur dans le message d'origine est un appel acquise () défini dans la boucle try. Voici une approche correcte pour utiliser le sémaphore "binaire" (Mutex):
la source
Pour vous assurer que a
Semaphore
est binaire, vous devez simplement vous assurer que vous passez le nombre de permis à 1 lors de la création du sémaphore. Les Javadocs ont un peu plus d'explications.la source
Le verrou de chaque objet est peu différent de la conception Mutex / Semaphore. Par exemple, il n'existe aucun moyen d'implémenter correctement la traversée des nœuds liés en libérant le verrou du nœud précédent et en capturant le suivant. Mais avec mutex, il est facile de mettre en œuvre:
Actuellement, il n'existe pas de classe de ce type dans
java.util.concurrent
, mais vous pouvez trouver l'implémentation de Mutext ici Mutex.java . Quant aux bibliothèques standard, Semaphore fournit toutes ces fonctionnalités et bien plus encore.la source