2017-04-22 12 views
22

मैं जावा 9 की नई सुविधाओं की जांच करने में काफी समय लगा रहा हूं, लेकिन मुझे कोई उपयोगी और व्यावहारिक उदाहरण नहीं मिला।जावा 9 में वरहैंडल का उपयोग करने का सही तरीका?

class Counter { 
    int i; 
} 

class VarHandleInAction { 
    static final VarHandle VH_COUNTER_FIELD_I; 

    static { 
     try { 
      VH_COUNTER_FIELD_I = MethodHandles.lookup(). 
       in(Counter.class). 
       findVarHandle(Counter.class, "i", int.class); 
     } catch (Exception e) { 
      // ... 
     } 
    } 
} 

लेकिन आगे क्या है:

कि एक VarHandle बनाता है अगले कोड स्निपेट पर विचार करें? मेरा मतलब है, इस परिवर्तनीय हैंडल का उपयोग कैसे करें? क्या आप कोई वास्तविक उदाहरण प्रदान कर सकते हैं?

+9

वार हैंडल (या विधि संभालती है) के बजाय कर रहे हैं विधि आमंत्रण और स्मृति संचालन के लिए निम्न स्तर के एपीआई। अधिकांश लोगों को कभी भी उन एपीआई का उपयोग करने की आवश्यकता नहीं होगी। –

उत्तर

24

यह AtomicReference में उदाहरण के लिए प्रयोग किया जाता है, जहां पहले से जावा 8 में, sun.misc.Unsafe इस्तेमाल किया गया था:

public final void lazySet(V newValue) { 
    unsafe.putOrderedObject(this, valueOffset, newValue); 
} 

public final boolean compareAndSet(V expect, V update) { 
    return unsafe.compareAndSwapObject(this, valueOffset, expect, update); 
} 

यहाँ this सूचक एक क्षेत्र क्षेत्र तक पहुँचने के लिए ऑफसेट के साथ एक साथ प्रयोग किया जाता है। लेकिन यह असुरक्षित है, क्योंकि यह फ़ील्ड ऑफ़सेट long हो सकता है, और आप वास्तव में कुछ अलग-अलग पहुंच सकते हैं। हालांकि इस तरह से प्रदर्शन करने में प्रदर्शन लाभ होते हैं (यह वीएम को उदाहरण के लिए विशेष सीपीयू निर्देशों का उपयोग करने के लिए कहता है), और अन्य लोगों के कारण sun.misc.Unsafe का उपयोग किया गया है, भले ही यह आंतरिक है, और असुरक्षित API।

VarHandles के उद्देश्य का एक हिस्सा sun.misc.Unsafe में एक सुरक्षित समकक्ष के साथ संचालन को प्रतिस्थापित करना है। कौन सा the JEP में कहा गया है:

एक मानक साधन परिभाषित विभिन्न java.util.concurrent.atomic और sun.misc.Unsafe आपरेशन के समकक्ष आह्वान करने के लिए ...

लक्ष्य :

निम्नलिखित आवश्यक हैं लक्ष्यों:

  • सुरक्षा। भ्रष्ट स्मृति स्थिति में जावा वर्चुअल मशीन को रखना संभव नहीं है। उदाहरण के लिए, किसी ऑब्जेक्ट का एक फ़ील्ड केवल उन उदाहरणों के साथ अपडेट किया जा सकता है जो फ़ील्ड प्रकार में जा सकते हैं, या सरणी तत्व केवल सरणी के भीतर पहुंचा जा सकता है यदि सरणी अनुक्रमणिका सरणी सीमाओं के भीतर है।

  • ईमानदारी। ऑब्जेक्ट के किसी फ़ील्ड तक पहुंच एक ही एक्सेस नियमों का पालन करती है जैसे कि गेटफील्ड और पुटफील्ड बाइट कोड के साथ बाधा के अलावा कि किसी ऑब्जेक्ट का अंतिम फ़ील्ड अपडेट नहीं किया जा सकता है। (नोट: इस तरह की सुरक्षा और अखंडता नियम भी फ़ील्ड को पढ़ने या लिखने के लिए मेथडहैंडल्स पर लागू होते हैं।)

  • प्रदर्शन। प्रदर्शन विशेषताओं समकक्ष sun.misc.Unsafe संचालन के समान या समान होना चाहिए (विशेष रूप से, जेनरेट असेंबलर कोड लगभग समान मॉड्यूलो कुछ सुरक्षा जांच होना चाहिए जिन्हें दूर नहीं किया जा सकता है)।

  • उपयोगिता। एपीआई sun.misc.Unsafe एपीआई से बेहतर होना चाहिए।

तो जावा 9 में इन तरीकों इस तरह दिखेगा:

public final void lazySet(V newValue) { 
    VALUE.setRelease(this, newValue); 
} 

public final boolean compareAndSet(V expectedValue, V newValue) { 
    return VALUE.compareAndSet(this, expectedValue, newValue); 
} 

कहाँ VALUE एक VarHandle है इस तरह परिभाषित करते हैं:

private static final VarHandle VALUE; 
static { 
    try { 
     MethodHandles.Lookup l = MethodHandles.lookup(); 
     VALUE = l.findVarHandle(AtomicReference.class, "value", Object.class); 
    } catch (ReflectiveOperationException e) { 
     throw new Error(e); 
    } 
} 
संबंधित मुद्दे