खोज…


टिप्पणियों

Unsafe वर्ग एक प्रोग्राम को उन चीजों को करने की अनुमति देता है जो जावा कंपाइलर द्वारा अनुमत नहीं हैं। सामान्य कार्यक्रमों को Unsafe का उपयोग करने से बचना चाहिए।

चेतावनी

  1. यदि आप Unsafe APIs का उपयोग करके कोई गलती करते हैं, तो आपके एप्लिकेशन JVM को क्रैश करने और / या लक्षणों का प्रदर्शन करने के लिए उत्तरदायी होते हैं, जिनका निदान करना कठिन है।

  2. Unsafe API बिना सूचना के परिवर्तन के अधीन है। यदि आप इसे अपने कोड में उपयोग करते हैं, तो आपको जावा संस्करण बदलते समय कोड को फिर से लिखना पड़ सकता है।

परावर्तन sun.misc.Unsafe प्रतिबिंब के माध्यम से

public static Unsafe getUnsafe() {
    try {
        Field unsafe = Unsafe.class.getDeclaredField("theUnsafe");
        unsafe.setAccessible(true);
        return (Unsafe) unsafe.get(null);
    } catch (IllegalAccessException e) {
        // Handle
    } catch (IllegalArgumentException e) {
        // Handle
    } catch (NoSuchFieldException e) {
        // Handle
    } catch (SecurityException e) {
        // Handle
    }
}

sun.misc.Unsafe में एक निजी कंस्ट्रक्टर है, और स्थिर getUnsafe() विधि को getUnsafe() के एक चेक के साथ संरक्षित किया जाता है ताकि यह सुनिश्चित हो सके कि कोड को प्राथमिक getUnsafe() साथ लोड किया गया था। इसलिए, आवृत्ति को लोड करने का एक तरीका स्थिर क्षेत्र को प्राप्त करने के लिए प्रतिबिंब का उपयोग करना है।

इंस्टेंटिंग sun.misc.Unsafe बूटक्लासपथ के माध्यम से

public class UnsafeLoader {
    public static Unsafe loadUnsafe() {
        return Unsafe.getUnsafe();
    }
}

हालांकि यह उदाहरण संकलित करेगा, यह तब तक विफल रहने की संभावना है जब तक कि अनसेफ क्लास को प्राथमिक क्लास लोडर के साथ लोड नहीं किया गया था। यह सुनिश्चित करने के लिए कि जेवीएम को उपयुक्त तर्कों से भरा जाना चाहिए, जैसे:

java -Xbootclasspath:$JAVA_HOME/jre/lib/rt.jar:./UnsafeLoader.jar foo.bar.MyApp

foo.bar.MyApp वर्ग तो उपयोग कर सकते हैं UnsafeLoader.loadUnsafe()

असुरक्षित होने का उदाहरण

असुरक्षित को एक निजी फ़ील्ड के रूप में संग्रहीत किया जाता है जिसे सीधे एक्सेस नहीं किया जा सकता है। कंस्ट्रक्टर निजी है और public static Unsafe getUnsafe() को एक्सेस करने का एकमात्र तरीका विशेषाधिकार प्राप्त है। परावर्तन के उपयोग से, निजी क्षेत्रों को सुलभ बनाने के लिए काम-काज होता है:

public static final Unsafe UNSAFE;

static {
    Unsafe unsafe = null;

    try {
        final PrivilegedExceptionAction<Unsafe> action = () -> {
            final Field f = Unsafe.class.getDeclaredField("theUnsafe");
            f.setAccessible(true);

            return (Unsafe) f.get(null);
        };

        unsafe = AccessController.doPrivileged(action);
    } catch (final Throwable t) {
        throw new RuntimeException("Exception accessing Unsafe", t);
    }

    UNSAFE = unsafe;
}

असुरक्षित के उपयोग

असुरक्षित के कुछ उपयोग इस प्रकार हैं:

उपयोग एपीआई
बंद ढेर / प्रत्यक्ष स्मृति आवंटन, वसूली और निपटान allocateMemory(bytes) , reallocateMemory(address, bytes) और freeMemory(address)
स्मृति बाड़ loadFence() , storeFence() , fullFence()
पार्किंग वर्तमान धागा park(isAbsolute, time) , unpark(thread)
प्रत्यक्ष फ़ील्ड और या मेमोरी एक्सेस get* और put* तरीकों में से परिवार
अनियंत्रित अपवादों को फेंकना throwException(e)
कैस और परमाणु संचालन compareAndSwap* तरीकों का परिवार
मेमोरी सेट करना setMemory
अस्थिर या समवर्ती संचालन get*Volatile , put*Volatile , putOrdered*

विधियों का परिवार और पुट परिवार किसी दिए गए ऑब्जेक्ट के सापेक्ष है। यदि ऑब्जेक्ट अशक्त है तो इसे एक पूर्ण पते के रूप में माना जाता है।

// Putting a value to a field
protected static long fieldOffset = UNSAFE.objectFieldOffset(getClass().getField("theField"));
UNSAFE.putLong(this, fieldOffset , newValue);

// Puting an absolute value
 UNSAFE.putLong(null, address, newValue);
 UNSAFE.putLong(address, newValue);

कुछ तरीकों को केवल int और longs के लिए परिभाषित किया जाता है। आप तैरता पर इन तरीकों का उपयोग कर सकते हैं और का उपयोग कर डबल्स floatToRawIntBits , intBitsToFloat, doubleToRawLongBits , longBitsToDouble`



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow