Maison > Questions et réponses > le corps du texte
Java synchronized(t)这个关键字修饰的代码块,意思是说获得t的锁之后,才能运行代码块。那么问题来了,如何知道某个对象t,是否被这样锁住了呢?
高洛峰2017-04-17 17:55:17
La classe Object du JDK ne fournit pas d'API pour déterminer si le verrou d'objet d'un objet est verrouillé. Mais les idées suivantes peuvent être réalisables.
La disposition d'un objet en mémoire comprend les parties suivantes
En-tête d'objet
Données d'instance d'objet (non concernées ici)
Rembourrage aligné (non concerné ici)
L'en-tête de l'objet contient certaines métadonnées de cet objet, dont deux parties : un champ de mot de marque et un champ de classe
Le mot de marque contient un indicateur de verrouillage. Lorsque l'objet n'est pas verrouillé, le flag est à 0, sinon il est à 1.
La taille du mot de marque est également différente selon les plateformes :
For 32 bit JVM:
_mark : 4 byte constant
_klass : 4 byte pointer to class
For 64 bit JVM:
_mark : 8 byte constant
_klass : 8 byte pointer to class
For 64 bit JVM with compressed-oops:
_mark : 8 byte constant
_klass : 4 byte pointer to class
Par conséquent, tant que vous pouvez obtenir le mot-clé, vous pouvez obtenir le drapeau de verrouillage, et vous pouvez alors savoir si un objet est verrouillé. Cependant, dans le JDK, nous ne pouvons exploiter que les données d'instance (variables et méthodes) de l'objet, et il n'y a aucun moyen d'obtenir l'en-tête de l'objet. Par conséquent, vous devrez peut-être utiliser la "technologie noire" en Java sun.misc.Unsafe
.
Prenons l'exemple du jdk 32 bits :
Object obj = new Object();
int markword = unsafe.getInt(obj, 0L);
Le 0L ici est le décalage.
Ensuite, effectuez une petite opération sur le mot-clé. L'auteur doit rechercher le contenu spécifique dans le mot-clé.
Pour en revenir à la question de l'affiche originale, peut-être que l'affiche originale veut juste un moyen de savoir si le verrou est maintenu, et n'a pas nécessairement à se préoccuper de la question de savoir si l'objet t est synchronisé.
Si tel est le cas, l'affiche peut abandonner le mot-clé synchronisé et utiliser ReentrantLock dans juc à la place. Il existe une méthode pour déterminer si le verrou est maintenu isLocked()