8
votes

Qu'est-ce que RetrantLock # Trylock (Long, TimeUnit) fait quand il essaie d'omettre l'égard de la serrure?

Quelle est la mise en œuvre de la réentrantlock # Trylock (longue, TimeUnit) qui essaie d'omettre une serrure? Supposons un filetage A Possède une erreur de verrouillage de MyLock et de thread b appel myock.tryLock (10, secondes) est le fil b endormi ou en attente?

En d'autres termes , était la différence de cette 2 implémentations:

1. xxx

2. xxx


1 commentaires

Dans votre code (2), vous n'enregistrez pas le thread à notifier lorsque le verrou est publié, vous tentez plutôt de l'interroger. Globalement, le code serait mieux sur w / juste readock.lock ()


5 Réponses :


0
votes

Je suppose que la seconde attendra que 5 millisecondes reçoivent une différence de verrouillage avec le premier qui tentera de verrouiller immédiatement. Donc, le fil b attendra si dans 5 ms (dans les 5 ms), le verrouillage ne reçoit pas de verrouillage, il reviendra de faux. Normalement, il n'y a pas de différence si vous avez 5 ms dans votre délai d'attente, mais si vous incrémentez ce numéro, vous obtiendrez l'image claire.

5ms est un délai d'attente, il attendra 5 ms pour un verrou qui signifie que si le verrou est disponible après 3 ms, il reviendra après 3 ms avec true.


2 commentaires

Trylock (long, timeunit) n'attend pas avant d'essayer d'obtenir la serrure, le [Javadoc] (" docs.oracle.com/javase/1.5.0/docs/aplia/java/util/c oncurrent / ... , java.util.concurrent.timeunit) ")") Dites: "Si le verrouillage est disponible, cette méthode renvoie immédiatement la valeur true."


@Chriss c'est exactement ce que je veux dire. Je n'ai pas dit que cela attendrait avant qu'il faudra une serrure, je suis triste de pouvoir attendre un 5 ms pour l'obtenir.



3
votes

Tout d'abord, la seconde attendra moins de 5 millis si le verrou est libéré, car il n'a pas besoin d'attendre pour se réveiller à partir du Dormir . Donc, c'est moins exposé au problème de la famine.

ALORS, J.U.C.L Package utilise des méthodes de stationnement SerruresUpport # pour mettre en pause un thread, pas thread.sleep . Et si je comprends bien, cela fait la différence sur le planificateur de fil, le parc permet une latence inférieure, mais pas sûr de la mise en œuvre exacte au

En outre, votre code n'a aucun sens, exactement le même effet pourrait être atteint par verrouillage () méthode.


3 commentaires

Sauf s'il y a un autre code qui doit être exécuté tous les cinq millisecondes sur ce fil.


@Erickrobertson à droite, c'est le point! Je veux utiliser l'un des extraits pour éviter une impasse. Je pense que je dois dormir, donc un autre thread peut progresser entre-temps et, espérons-le, libérer une autre serrure.


@Chriss the verrouillage () sous l'appels de capot java.util.concurrent.lock.util.concurrent.locks.locksupport # Park Lequel " désactive le thread de courant à des fins de planification de la fil permis est disponible. ". Cela signifie que tous les autres threads devraient faire des progrès, le fil actuel est dormant. Je ne vois pas comment cela pourrait aider à résoudre des blocages, seulement peut-être en diminuant la probabilité d'impasse, en resserrant une fenêtre de condition de course au prix de la latence accrue.



1
votes

Techniquement, il n'y a pas de différence en ce qui concerne l'état du fil d'attente. De la Javadoc:

Si le verrou est maintenu par un autre thread, le thread de courant devient désactivé Pour des fins de planification du fil et se situe dormant [...]

Ceci est très similaire à ce qui se passe en cas de dormir, mais je suppose que nous ne pouvons pas dire avec certitude que si nous connaissons la mise en œuvre.

Maintenant, note cette partie:

[...] est dormant jusqu'à ce que l'une des trois choses se passe: La serrure est acquise par le fil actuel; ou [...]

Cela signifie que si le verrou devient libre entre-temps, il l'acquérira et retournera. Dans l'autre cas, alors qu'il dort, le fil n'a aucune chance d'obtenir la serrure même si elle est gratuite.

Une autre différence subtile pouvant apparaître entre les deux cas est le fait que la stratégie chronométrée est sensible à la politique d'équité de la réentrantlock. C'est:

Si ce verrou soit défini pour utiliser une stratégie de commande équitable, un verrouillage disponible ne sera pas acquis si d'autres threads attendent la serrure.

Le député inexprimé est connu pour ne pas être juste et peut réussir à acquérir la serrure même si d'autres threads l'attendent déjà.


0 commentaires

1
votes

, il attend le verrou et le fil est endormi.

interne, si le trackock (long, timeulit) La méthode ne parvient pas à acquérir le verrou, il attend le temps spécifié. Si la serrure devient disponible avant cette durée, elle renvoie immédiatement avec la serrure. Notez que dans ce cas, lorsqu'il existe plusieurs threads demandant une serrure, le reentrantlock choisira au hasard un fil pour donner le verrou à la prochaine. Ce comportement peut être modifié en passant true à la valeur d'équité dans le constructeur nouveau reentrantlock (true) .

Le deuxième exemple ne vérifiera que la serrure tous les cinq millisecondes. Si la serrure devient disponible pendant son sommeil et est donnée à un autre fil avant de se réveiller, ce fil sera indisponible pour l'acquisition de la serrure.

Si vous utilisez ce code avec de nombreux threads en attente de la serrure, notez que aucune solution que vous avez fournie garantira que chaque thread obtiendra la serrure à un moment donné. Le deuxième code peut continuer à se faire snipé par un autre fil juste avant que les cinq millisecondes soient en place. Le premier code est aléatoire, mais même avec la valeur de la valeur d'équité, chaque thread abandonnera sa place en ligne toutes les cinq millisecondes. Si tel est le cas, vous ferez mieux d'augmenter la valeur du délai d'expiration. Un bon rapport qualité-prix serait sur le double de la durée maximale que vous vous attendriez à prendre pour chaque thread pour obtenir un tour.


1 commentaires

Notez que dans ce cas, lorsqu'il y a plusieurs threads demandant une serrure, le RetrantLock choisira un thread de manière aléatoire pour donner le verrou à la prochaine. Ce n'est pas exactement vrai, il choisira le premier fil du File d'attente des threads Waiting dans une version non juste. Mais si un autre fil (s) tente d'acquérir la serrure pendant le temps qu'il est libéré (avant l'impuissance d'un serveur), il peut l'acquérir - d'où le dernier thread peut devenir d'abord. Les serveurs sont généralement réveillés par l'ordre, puis entrez dans la file d'attente d'attente. La version juste exige que le propriétaire du verrou soit le 1er serveur.



0
votes

Pour une excellente référence sur la manière dont les serrures et autres primitives de concurrence sont implémentés, voir Shavit et Herlihy's excellent L'art de la programmation multiprocesseur .


0 commentaires