Vorwort
In diesem Artikel wird hauptsächlich relevante Inhalte über die unsichere Klasse in Java eingeführt. Es wird für Ihre Referenz und Ihr Lernen geteilt. Ich werde unten nicht viel sagen. Schauen wir uns die detaillierte Einführung gemeinsam an.
1. Einführung der unsicheren Klasse
Die unsichere Klasse befindet sich unter der Sonne.misc -Paket und gehört nicht zum Java -Standard. Viele Java Basic-Klassenbibliotheken, einschließlich einiger weit verbreiteter Hochleistungs-Entwicklungsbibliotheken, werden jedoch auf der Grundlage einer unsicheren Klasse entwickelt, wie Netty, Hadoop, Kafka usw.
Unsicher werden verwendet werden, um direkt auf Systemspeicherressourcen zuzugreifen und unabhängig zu verwalten. Die unsichere Klasse spielt eine große Rolle bei der Verbesserung der Effizienz des Java -Betriebs und der Verbesserung der zugrunde liegenden Betriebsfunktionen der Java -Sprache.
Unsicher werden als Hintertür in Java angesehen werden und bieten einige Vorgänge auf niedrigem Niveau, wie z. B. direkten Speicherzugriff, Thread-Planung usw.
Unsicher wird nicht empfohlen.
Hier sind einige Beispiele für die Verwendung von Unsicherheit.
1.1 eine private Klasse instanziieren
Import Java.lang.reflect.field; import sun.misc.unsafe; öffentliche Klasse Unsafeplayer {public static void main (String [] args) löst eine Ausnahme aus {// unsicheres Feld f = unsicher.class.getDeclaredfield ("theunsafe"); f.setAccessible (wahr); Unsicher unsicher = (unsicher) f.get (null); // Sofortarbeiter Player Player = (Player) unsicher.AllecocateInstance (Player.Class); Player.SetName ("li lei"); System.out.println (Player.getName ()); }} class Player {privater String -Name; private Player () {} public String getName () {return name; } public void setName (String -Name) {this.name = name; }} 1.2CAS -Betrieb ändern Sie den Wert des Messgeräts durch Speicherversetzungsadressenänderung Änderung
Verwenden Sie CAS, um die Oberseite des Stapels in Synchronousqueue im Java -Concurrency -Paket in Synchronousqueue zu aktualisieren.
/ Unsichere Mechanics -private statische endgültige Sonne.Misc.unsafe unsicher; Klasse <?> K = transferStack.class; HeadOffset = unafe.ObjectfieldOffset (k.getDeclaredfield ("head")); } catch (Ausnahme E) {Neuen Fehler werfen (e); }} // Volatile Snode Head; // Die Oberseite des stack boolean Cead (snode h, snode nh) {return h == head && unafe.comPoneswapObject (this, HeadOffset, H, NH);}; 1.3 Direkter Speicherzugriff
Der direkte Speicherzugriff von Unsicherheit: Der mit unsicher geöffnete Speicherplatz belegt keinen Leerraum und hat natürlich keine automatische Speicherwiederherstellungsfunktion. Ermöglichen Sie es, Systemspeicherressourcen frei wie C zu verwenden, wie C.
2. Analyse unsicherer Klassenquellencode -Code
Die meisten APIs von Unsicheren sind native Methoden, hauptsächlich die folgenden Kategorien:
1) Klassenbezogen. Bietet hauptsächlich Klasse und statische Felder Betriebsmethoden.
2) Objekt verwandt. Bietet hauptsächlich die Betriebsmethoden des Objekts und seiner Felder.
3) arrray verwandt. Bietet hauptsächlich die Betriebsmethoden von Arrays und Elementen darin.
4) gleichzeitige Korrelation. Es liefert hauptsächlich Synchronisationsprimitive mit niedriger Ebene wie CAS, Gewindeplanung, flüchtiger, Speicherbarriere usw.
5) Speicherbezogen. Es bietet eine direkte Speicherzugriffsmethode (umgehen des Java -Heaps und der direkten Manipulation des lokalen Speichers), das die Systemspeicherressourcen wie C frei nutzen kann
6) Systembezogen. Es gibt hauptsächlich einige Speicherinformationen auf niedriger Ebene zurück, z. B. die Größe der Adressgröße und die Größe der Speicherseite.
2.1 Klassenbezogen
// Der Versatz statischer Attribute wird verwendet, um statische Attribute im entsprechenden Klassenobjekt Public Native Long StaticfieldOffset (Feld F) zu lesen und zu schreiben. Public Native Object staticfieldbase (Feld f); // beurteilen, ob eine Klasse initialisiert werden muss. Classloader Loader, ProtectionDomain ProtectionDomain); // Definieren Sie eine anonyme Klasse, mit der die klassenklasse klassen <?> DefineanonyusClass dynamisch erstellt werden kann (Klasse <?> HostClass, Byte [] Daten, Objekt [] Cppatches);
2.2Object bezogen
Es gibt die folgenden Methoden für Grundtypen (Boolean, Byte, char, Short, Int, Long, Float, Double) und Objektreferenztypen in Java.
// den Feldversatz des Objekts öffentlich native Long ObjectFieldOffset (Feld F) erhalten; // Erhalten Sie den int -Wert des angegebenen Objektadresses Offset Public Native Int GetInt (Objekt O, Long Offset); // Setzen Sie den int -Wert des angegebenen Objektadresses Offset Public native void putint (Objekt O, langer Offset, int x);
// Erstellen Sie ein Objekt, aber sein Konstruktor wird nicht aufgerufen. Wenn die Klasse nicht initialisiert wird, wird die Klasse initialisiert. Public Native Object -AllocationInstance (Klasse <?> Cls) löst eine Instanziationspflicht aus;
2.3 Array verwandt
/** * Melden Sie den Offset des ersten Elements in der Speicherzuweisung einer * angegebenen Array -Klasse. Wenn {@link #ArrayIndexscale} einen Wert ungleich Null * für dieselbe Klasse zurückgibt, können Sie diesen Skalierungsfaktor zusammen mit diesem * Basisversatz verwenden, um neue Offsets zu bilden, um auf Elemente von Arrays der * angegebenen Klasse zuzugreifen. * * @see #getInt (Objekt, lang, int) * /// Die Offset -Adresse des ersten Elements im Array public native int arrayBaseoffset zurückgeben (Klasse <?> ArrayClass); // Boolesche, Byte, Short, Char, Int, Long, Float, Double und Objectypen haben die folgenden Methoden/** Der Wert von {@Code -Architen -Archn -Arga -St. -Class (booolean []. Class). Array_Boolean_base_offset = theunsafe.ArrayBaseOffset (boolean []. Klasse); /** * Melden Sie den Skalierungsfaktor für die Adressierung von Elementen in der Speicherung * Zuweisung einer bestimmten Array -Klasse. Arrays von "engen" Typen * funktionieren jedoch im Allgemeinen nicht ordnungsgemäß mit Zubehör wie {@link * #getByte (Objekt, int)}, sodass der Skalierungsfaktor für solche Klassen * als Null angegeben wird. * * @see #ArrayBaseOffset * @see #getInt (Objekt, lang) * @see #putint (Objekt, lang, int) * /// RECHT Die Größe, die jedes Element im Array Public native int arrayIndexscale (Klasse <?> ArrayClass) besetzt ist; // Boolean, Byte, Short, Char, Int, Long, Float, Double und Objekttypen haben die folgenden Methoden/** Der Wert von {@Code arrayIndexscale (boolean []. Klasse)}*/public static endgültig intarray_boolean_index_scale = theunsafe.arrayIndexscale (boolean []. Die Position jedes Elements im Array im Speicher kann über ArrayBaseOffset und ArrayIndexscale gefunden werden.
2.4 Parallelitätsbezogen
2.4.1cas verwandt
CAS: Vergleichswap, Speicher -Offset -Adressversatz, erwarteter Wert erwartet, neuer Wert x. Wenn der Wert der Variablen zum aktuellen Zeitpunkt und der erwartete Wert gleich sind, versuchen Sie, den Wert der Variablen nach x zu aktualisieren. Rückgabe true, wenn das Update erfolgreich ist. Ansonsten kehren Sie falsch zurück.
// Aktualisieren Sie den Variablenwert auf x, wenn der aktuelle Wert erwartet wird // O: Objektversetzt: Offset erwartet: Erwartter Wert X: Neuer Wert öffentliche endgültige native boolesche Vergleichewapobject (Objekt O, Long Offset, Objekt erwartet, Objekt X); Public Final Native Boolean VergleicheSwapint (Objekt O, Long Offset, int erwartet, int x); Public Final Native Boolean VergleicheSwaplong (Objekt O, Long Offset, Long Aduct, Long x);
Ab Java 8 sind die folgenden Methoden in unsicherem:
// Public Final int getandAdDint (Objekt O, Long Offset, int Delta) {int v; do {v = getIntvolatile (o, offset); } while (! VergleicheDSwapint (O, Offset, V, V + Delta)); return v;} public Final Long getandaddlong (Objekt O, langer Offset, langes Delta) {long v; do {v = getlongvolatile (o, offset); } while (! vergleicheStwaplong (o, offset, v, v + delta)); return v;} // Setzen Sie die öffentliche endgültige int getAndSetint (Objekt O, Long Offset, int NewValue) {int v; do {v = getIntvalatile (o, offset); } while (! VergleicheDSwapint (O, Offset, V, NewValue)); return v;} public Final Long GetandsetLong (Objekt O, langer Offset, Long NewValue) {long v; do {v = getlongvalatile (o, offset); } while (! VergleicheDSwaplong (O, Offset, V, NewValue)); return v;} öffentliches endgültiges Objekt getAndObject (Objekt O, langer Offset, Objekt NewValue) {Objekt v; do {v = getObjectValatile (o, offset); } while (! vergleicheDSWAPObject (O, Offset, V, NewValue)); Rückkehr v;2.4.2 Thread -Planung verwandt
// Abblockieren von Thread Public native void Unpark (Objekt -Thread); // Blockierung von Thread Public Native Void Park (boolean isabsolute, langjährige); // Objektverriegelung öffentliche native void monitorenterung (Objekt O); // Objektverriegelung öffentliche native void monitorexit (Objekt O); // Versuch, Objektverriegelung zu erhalten, echte oder falsche, addiert, ob es erfolgreich ist, ob es erfolgreich ist, ob es erfolgreich ist.
2.4.3 Flüchtige Lesen und Schreiben
Es gibt die folgenden Methoden für Grundtypen (Boolean, Byte, char, Short, Int, Long, Float, Double) und Objektreferenztypen in Java.
// Erhalten Sie die Referenz der Variablen aus dem angegebenen Versatz des Objekts und verwenden Sie die Lastsemantik des flüchtigen // äquivalenten der flüchtigen Version von GetObject (Objekt, langes) öffentliches natives Objekt GetObjectVolatile (Objekt O, Long Offset); // Speichern Sie die Referenz der Variablen auf den angegebenen Offset des Objekts und verwenden Sie die Speichersemantik des flüchtigen // äquivalenten der flüchtigen Version von PutObject (Object, Long, Object).
/** * Version von {@link #putObjectVolatile (Objekt, lang, Objekt)} * Das garantiert keine sofortige Sichtbarkeit des Speichers für * andere Threads. Diese Methode ist im Allgemeinen nur nützlich, wenn das zugrunde liegende Feld ein flüchtiges Java ist (oder wenn eine Array -Zelle, eine *, auf die sonst nur mit volatilen Zugriffen zugegriffen wird). */public native void putOrderedObject (Objekt O, langer Offset, Objekt x); /** Ordered/Lazy Version von {@link #putintvolatile (Objekt, lang, int)}*/public native void putordedInt (Objekt O, langer Offset, int x); /** bestellt/faul von {@link #putlongvolatile (Objekt, lang, lang)}*/public native void putordedlong (Objekt O, langer Offset, lang x);2.4.4 Speicherbarriere verwandt
Java 8 wurde eingeführt, um Gedächtnisbarrieren zu definieren, um eine Neuordnung von Code zu vermeiden.
//Memory barrier, prohibits load operations from being reordered, that is, load operations before the barrier cannot be reordered to the barrier, load operations after the barrier cannot be reordered to the front of the barrier public native void loadFence();//Memory barrier, prohibits store operations before the barrier, prohibits store operations after the barrier, public native void storeFence();//Memory barrier, prohibits Last- und Speichern von Operationen von der Vorderseite der Barriere Public Native Void Fullfence ();
2.5 Direkter Speicherzugriff (Nicht-Heizspeicher)
Der von Allocatememory zugewiesene Gedächtnis muss manuell frei sein (nicht von GC recycelt)
// (Boolean, Byte, Char, Short, Int, Long, Float, Double) haben die folgenden zwei Methoden: Holen Sie sich und setzen Sie. // den int -Wert an die angegebene Adresse öffentlich native int GetInT (lange Adresse) erhalten; // Setzen Sie den int -Wert an der angegebenen Adresse öffentlich native void putint (lange Adresse, int x); // Holen Sie sich den lokalen Zeiger öffentlich native long GetAddress (lange Adresse); // Speichern Sie den lokalen Zeiger auf die angegebene Speicheradresse öffentlich native void putaddress (lange Adresse, lange X). // Speicher öffentliche native lange allokatemory (lange Bytes); // Memory Memory Native Long Reallocatemory (lange Adresse, lange Bytes); // Initialisieren des Speicherinhalts öffentlich native void setMemory (Objekt O, langer Offset, lange Bytes, Byte); // Initialisieren des Gedächtnisses Inhalt öffentlich -void -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set -Set. 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, Bytes);} // Speicher öffentlich native void freememory (lange Adresse); 2.6 Systembezogen
// Die Größe des Zeigers zurückgibt. Der Rückgabewert beträgt 4 oder 8. Public Native Int adressize (); /** Der Wert von {@Code adressSize ()}*/public static Final int adress_size = theunsafe.addressSize (); // die Größe der Speicherseite. öffentliche native int pageSize ();3. Referenzmaterialien
//www.vevb.com/article/140709.htm, lass uns über die unsichere Klasse in Java sprechen
//www.vevb.com/article/140721.htm Java Magic Class: sun.misc.unsafe
Zusammenfassen
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Referenzwert für das Studium oder die Arbeit eines jeden hat. Wenn Sie Fragen haben, können Sie eine Nachricht zur Kommunikation überlassen. Vielen Dank für Ihre Unterstützung bei Wulin.com.