Considérons la synchronisation standard suivante en Java:Java - comment Lock garantit-il la relation qui se passe avant?
public class Job {
private Lock lock = new ReentrantLock();
public void work() {
lock.lock();
try {
doLotsOfWork();
} finally {
lock.unlock();
}
}
}
Je comprends, basé sur Javadoc, que cela équivaut à synchronized
bloc. J'ai du mal à voir comment cela est effectivement appliqué au niveau inférieur.
Lock
a un état qui est volatile, lors de l'appel à lock()
il fait une lecture volatile, puis lors de la libération, il effectue une écriture volatile. Comment une écriture dans un état d'un objet peut-elle garantir que aucune des instructions de doLotsOfWork
, qui pourrait toucher beaucoup d'objets différents, ne sera exécutée dans le désordre?
Ou imaginez que doLotsOfWork est effectivement remplacé par 1000+ lignes de code. Il est clair que le compilateur ne peut pas savoir à l'avance qu'il y a un volatile quelque part à l'intérieur de la serrure, donc il doit arrêter de réorganiser les instructions. Alors, comment cela se passe - avant garanti pour lock/unlock
, même si elle est construite autour de l'état volatile d'un objet séparé?
Je ne vois aucune volatilité dans l'implémentation Lock/ReentrantLock. Vous pouvez vérifier l'implémentation de ReentraltLock à l'adresse suivante: http://grepcode.com/file_/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/concurrent/locks/ReentrantLock.java/?v= source –
Via son implémentation. Ce n'est pas défini. Seulement requis. – EJP
L'état de AbstractQueuedSYnchronizer est une variable volatile – Bober02