Préface
Cet article présente principalement un contenu pertinent sur la classe dangereuse à Java. Il est partagé pour votre référence et votre apprentissage. Je ne dirai pas beaucoup en dessous. Jetons un coup d'œil à l'introduction détaillée ensemble.
1. Introduction de classe dangereuse
La classe dangereuse est sous le package Sun.Misc et n'appartient pas à la norme Java. Cependant, de nombreuses bibliothèques de classe Java Basic, y compris certaines bibliothèques de développement haute performance largement utilisées, sont développées sur la base d'une classe dangereuse, telle que Netty, Hadoop, Kafka, etc.
Disé peut être utilisé pour accéder directement aux ressources de mémoire système et à gérer indépendamment. La classe dangereuse joue un grand rôle dans l'amélioration de l'efficacité de l'opération Java et l'amélioration des capacités de fonctionnement sous-jacentes de la langue Java.
Danget peut être considéré comme une porte dérobée à Java, offrant des opérations de bas niveau, telles que l'accès direct à la mémoire, la planification des threads, etc.
Disé n'est pas recommandé.
Voici quelques exemples d'utilisation dangereuse.
1.1 Instancier une classe privée
import java.lang.reflect.field; IMPORT SUN.MISC.UNSAFE; classe publique Unplayer {public static void main (String [] args) lève une exception {// Instanciate Unsafe Field f = unsepe.class.getDeclaredField ("TheunSafe"); f.setAccessible (true); Dangereux dangereux = (dangereux) f.get (null); // Instanciate Player Player Player = (Player) Unsetafe.ALLOCOSIANTANCE (Player.class); player.setName ("Li lei"); System.out.println (player.getName ()); }} class Player {name de chaîne privée; Player Player () {} public String getName () {Nom de retour; } public void setName (string name) {this.name = name; }} 1.2CAS Opération, modifiez la valeur du compteur à travers la modification de l'adresse de décalage de mémoire
Utilisez CAS pour mettre à jour le haut de la pile dans Transferstack dans SynchronousQueue dans le package concurrentiel Java.
/ Mécanique dangereuse privative finale statique finale.Misc.unsafe dangereuse; rejet à bout final statique statique privé; statique {try {unpae = Sun.Misc.unsafe.getUnSafe (); Classe <?> K = transferstack.class; Headoffset = unsetafe.ObjectFieldOffset (k.getDeclaredField ("Head")); } catch (exception e) {lancer une nouvelle erreur (e); }} // tête de snode volatile; // Mettez à jour le haut de la caisse booléenne de pile (snode h, snode nh) {return h == head && danged ......panceswapObject (this, kimpset, h, nh);}; 1.3 Accès à la mémoire directe
Accès à la mémoire directe de Disap: l'espace mémoire ouvert avec dangereux n'occupe pas d'espace de tas, et bien sûr, il n'a pas de fonction de récupération de mémoire automatique. Permettez à utiliser librement les ressources de mémoire système comme C.
2. Analyse de code source de classe dangereuse
La plupart des API de dangereuse sont des méthodes natives, y compris principalement les catégories suivantes:
1) lié à la classe. Fournit principalement la classe et ses méthodes de fonctionnement de champs statiques.
2) lié à l'objet. Fournit principalement les méthodes de fonctionnement de l'objet et de ses champs.
3) lié à l'arrray. Fournit principalement les méthodes de fonctionnement des tableaux et des éléments.
4) Corrélation simultanée. Il fournit principalement des primitives de synchronisation de bas niveau, telles que le CAS, la planification du thread, la volatile, la barrière de mémoire, etc.
5) lié à la mémoire. Il fournit une méthode d'accès à la mémoire directe (contournant le tas Java et manipulant directement la mémoire locale), qui peut utiliser librement des ressources de mémoire système comme C.
6) lié au système. Il renvoie principalement certaines informations de mémoire de bas niveau, telles que la taille de l'adresse et la taille de la page de mémoire.
2.1 Class lié
// Le décalage des attributs statiques est utilisé pour lire et écrire des attributs statiques dans l'objet de classe correspondant public natif Long StaticFieldoffset (champ F); objet natif public staticfieldBase (champ f); // juger si une classe doit être initialisée booléenne native publique devrait être abrégée (classe <?> c); // s'assurer que la classe est initialisée publique native void assureclassinitialized (classe <?> c); // définir une classe qui peut être utilisée pour créer dynamiquement la classe native <? chargeur, protectionDomain ProtectionDomain); // définir une classe anonyme qui peut être utilisée pour créer dynamiquement des classes publiques Classe native <?> DefianonymousClass (classe <?> hostclass, byte [] data, objet [] cppatches);
2.2-OBJET
Il existe les méthodes suivantes pour les types de base (boolean, octets, char, court, int, long, flottant, double) et types de référence d'objet en Java.
// obtient le compensation du champ de l'objet public Long ObjectFieldOffset (champ F); // Obtenez la valeur int de l'adresse d'objet donnée Offset publique native int getInt (objet o, décalage long); // Définissez la valeur int de l'adresse d'objet donnée Offset Public Native void Pount (objet O, décalage long, int x);
// Créer un objet, mais son constructeur ne sera pas appelé. Si la classe n'est pas initialisée, la classe est initialisée. L'allocation d'objets natifs publics (classe <?> CLS) lève InstantiationException;
2.3 lié au tableau
/ ** * Signaler le décalage du premier élément dans l'allocation de stockage d'une classe de tableau donnée. Si {@Link #ArrayIndexScale} renvoie une valeur non nulle * pour la même classe, vous pouvez utiliser ce facteur d'échelle, ainsi que ce * décalage de base, pour former de nouveaux décalages pour accéder aux éléments des tableaux de la classe * donnée. * * @see #getInt (objet, long, int) * /// Renvoyez l'adresse de décalage du premier élément du tableau publique natif int arrayBaseOffset (classe <?> ArrayClass); // booléen, octet, court, char, int, long, flottant, double et objet Array_boolean_base_offset = theunsafe.ArrayBaseOffset (boolean []. Class); / ** * Signaler le facteur d'échelle pour résoudre les éléments dans l'allocation de stockage * d'une classe de tableau donnée. Cependant, les tableaux de types "étroits" ne fonctionneront généralement pas correctement avec des accessoires comme {@Link * #getByte (objet, int)}, de sorte que le facteur d'échelle pour de telles classes est signalé * comme zéro. * * @see #ArrayBaseOffSet * @see #getInt (objet, long) * @see #puntInt (objet, long, int) * /// Renvoie la taille occupée par chaque élément du tableau publique natif int arrayIndexscale (classe <?> ArrayClass); // Boolean, octet, court, char, int, long, float, double et objets types ont les méthodes suivantes / ** la valeur de {@code arrayIndexscale (boolean []. class)} * / public static final int array_boolean_index_scale = theunsafe.arrayindexscale (booolean []. L'emplacement de chaque élément dans le tableau en mémoire peut être situé via ArrayBaseOffset et ArrayIndexScale.
2.4 lié à la concurrence
2.4.1Cas liés
CAS: Comparandswap, décalage de décalage de mémoire décalage, valeur attendue attendue, nouvelle valeur x. Si la valeur de la variable à l'heure actuelle et la valeur attendue sont égales, essayez de mettre à jour la valeur de la variable à x. Retour True si la mise à jour est réussie; Sinon, retournez false.
// Mette à jour la valeur de la variable sur x, si la valeur actuelle est attendue // o: Offset d'objet: décalage attendu: valeur attendue x: nouvelle valeur publique finale native booléen comparabledswapObject (objet o, décalage long, objet attendu, objet x); Public Final Native Boolean CompareAndSwapint (objet O, décalage long, int attendu, int x); Public Final Native Boolean Comparanddswaplong (objet O, décalage long, attendu longtemps, long x);
En commençant par Java 8, les méthodes suivantes sont fournies en dangere:
// ajouter public final int getAndAddint (objet o, décalage long, int delta) {int v; do {v = getIntVolatile (o, offset); } while (! CompareAndSwapInt (o, offset, v, v + delta)); return v;} public final long getandaddlong (objet o, décalage long, long delta) {long v; do {v = getLongVolatile (o, offset); } while (! CompareAndSwapLong (o, offset, v, v + delta)); return v;} // Définir public final int GetAndSetInt (objet o, décalage long, int newValue) {int v; do {v = getIntValatile (o, offset); } while (! CompareAndSwapInt (o, offset, v, newValue)); return v;} public final long getAndSetLong (objet o, décalage long, long newValue) {long v; do {v = getLongValatile (o, offset); } while (! ComparandSwapLong (o, offset, v, newValue)); return v;} public final objet getAndSetObject (objet o, décalage long, objet newValue) {objet v; do {v = getObjectValatile (o, offset); } while (! CompareAndWapObject (o, offset, v, newValue)); retour v;2.4.2 Planification de threads liée
// Unblocking Thread Public Native void Uncark (Thread d'objet); // Blocking Thread Public Native void Park (Boolean Isabsolute, Long Time); // Get Object Lock Public Native Void Surverentiter (Objet O); // Libérez l'objet Lock Public Native Void Monitorexit (Objet O); // Essayez d'obtenir l'objet Lock, Retour True ou False pour indiquer si elle est réussie.
2.4.3 Lire et écriture liés à la volatile
Il existe les méthodes suivantes pour les types de base (boolean, octets, char, court, int, long, flottant, double) et types de référence d'objet en Java.
// Obtenez la référence de la variable à partir du décalage spécifié de l'objet et utilisez la sémantique de charge de volatile // équivalent à la version volatile de GetObject (objet, long) objet natif public GetObjectVolatile (objet O, décalage long); // Stockage La référence de la variable au décalage spécifié de l'objet et utilisez la sémantique de stockage de volatile // équivalent à la version volatile de putObject (objet, long, objet) public void putObjectVolatile (objet O, décalage long, objet x);
/ ** * Version de {@link #putObjectVolatile (objet, long, objet)} * qui ne garantit pas la visibilité immédiate du magasin à * d'autres threads. Cette méthode n'est généralement utile que si le champ sous-jacent est un volatile Java (ou si une cellule de tableau, une * qui est autrement accessible à l'aide d'accès volatils). * / public natif void putOrderEdObject (objet o, décalage long, objet x); / ** Version ordonnée / paresseuse de {@link #putIntVolatile (objet, long, int)} * / public native void putOrderEDInt (objet o, long décalage, int x); / ** version ordonnée / paresseuse de {@link #putlongVolatile (objet, long, long)} * / public native void putOrderEdLong (objet o, décalage long, long x);2.4.4 Barrière de mémoire liée
Java 8 a été introduit pour définir les barrières de mémoire pour éviter la réorganisation du code.
// barrière de mémoire, interdit aux opérations de charge d'être réorganisées, c'est-à-dire que les opérations de chargement avant que la barrière ne puisse être réorganisée à la barrière, les opérations de chargement après la barrière ne peuvent pas être réorganisées à l'avant de la barrière publique indigène Vend LoadFence (); // Barrière de mémoire, Prohibits Store Operations avant la barrière; Les opérations de chargement et de stockage de la réorganisation à l'avant de la barrière publique native void fullfence ();
2.5 Accès à la mémoire directe (mémoire non héapée)
La mémoire allouée par l'allocatémémoire doit être manuellement libre (non recyclée par GC)
// (booléen, octet, char, court, int, long, flottant, double) ont les deux méthodes suivantes: Get and Put. // Obtenez la valeur int à l'adresse donnée publique native int getInt (adresse longue); // Définissez la valeur int à l'adresse donnée publique native void Pount (adresse longue, int x); // Obtenir le pointeur local Native GetAddress (Adresse longue); // Stockage Le pointeur local vers l'adresse mémoire donnée Public Native PutAddress (Adresse longue, longue x); // allocation de la mémoire publique native allocatemémory (octets longs); // réalemlocat memoire public natif long reallocatemory (adresse longue, octets longs); // initialise le contenu de la mémoire publique natif void setMemory (objet o, décalage long, long octets, byte de la mémoire); // initialize le contenu de la mémoire SetMemory (Nullory (longue adresse, longue, longue address, bytes, value);}//Initialize the memory content public native void copyMemory(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes);//Initialize the memory content public void copyMemory(long srcAddress, long destAddress, long bytes) { copyMemory(null, srcAddress, null, destAddress, octets);} // Release Memory Public Native void freeMemory (longue adresse); 2.6 lié au système
// Renvoie la taille du pointeur. La valeur de retour est de 4 ou 8. Public Native int AddressSize (); / ** La valeur de {@code adresseSize ()} * / public static final intadress_size = theunsafe.addresssize (); // la taille de la page de mémoire. public native int pagesize ();3. Matériaux de référence
//www.vevb.com/article/140709.htm Parlons de la classe dangereuse à Java
//www.vevb.com/article/140721.htm Java Magic Class: Sun.Misc.unsafe
Résumer
Ce qui précède est l'intégralité du contenu de cet article. J'espère que le contenu de cet article a une certaine valeur de référence pour l'étude ou le travail de chacun. Si vous avez des questions, vous pouvez laisser un message pour communiquer. Merci pour votre soutien à wulin.com.