2013-07-13 24 views
11

स्कैला में, AnyRef पर एक सिंक्रनाइज़ विधि है जो आपको AnyRef को विस्तारित करने वाली किसी ऑब्जेक्ट पर सिंक्रनाइज़ करने देती है। हालांकि, यह AnyRef पर सार है, और मैं यह नहीं समझ पाया कि यह स्केल स्रोत को पकड़ने से कैसे काम करता है। ऐसा लगता है कि यह जावा में सिंक्रनाइज़ किए गए कीवर्ड का शोषण करके काम करता है। क्या यह मामला है?AnyRef पर सिंक्रनाइज़ विधि कैसे कार्यान्वित की जाती है?

उत्तर

25

1) AnyRef.synchronized एक जादू विधि है जो स्रोत कोड में मौजूद नहीं है, लेकिन संकलक के प्रत्येक स्टार्टअप पर कंपाइलर की प्रतीक तालिका में इंजेक्शन दिया जाता है: Definitions.scala। रास्ते में (Definitions.scala) कई जादू विधियों और कक्षाएं हैं।

2) एक विधि this.synchronized में लपेटा जाता है, तो रैपिंग गिरा दिया जाता है, और विधि आंतरिक रूप से एक SYNCHRONIZED ध्वज (UnCurry.scala) है, जो तब JVM के `ACC_SYNCHRONIZED विधि का उपयोग झंडा (GenASM.scala) करने के लिए मैप किया गया है के साथ टिप्पणी की जाती है।

3) synchronized को अन्य कॉल पर मैप की जाती हैं बैकएंड के आदिम SYNCHRONIZED (backend/ScalaPrimitives.scala) है, जो बाद में monitorenter/monitorexit (GenICode.scala #1, GenICode.scala #2) में उतारा गया है।

8

यूजीन से जवाब में जोड़ने के लिए, जो दिल से कंपाइलर को जानता है, यहां एक छोटा सा स्केल कंसोल सत्र है।

निचली पंक्ति: जेनरेट कोड बिल्कुल जावा जैसा होगा जो आप प्राप्त करेंगे। सिंक्रनाइज़ {...} और यहां तक ​​कि एक विधि कॉल के लिए उत्पन्न कोई बंद नहीं है। बस कोशिश करें/पकड़ो जहां कोशिश की शुरुआत में एक monitorenter बाइटकोड (3) है और दोनों सामान्य निकास (9) में कैच निकास (12) में एक monitorexit है। इसलिए जावा में इसका उपयोग कर स्कैला बनाम सिंक्रनाइज़ किए गए उपयोग में कोई ओवरहेड शामिल नहीं है।

ध्यान दें कि ज्यादातर लोग मानते हैं कि प्रत्येक वस्तु पर खतरनाक निम्न स्तर के थ्रेड सिंक्रनाइज़ेशन संरचनाओं को आम तौर पर एक बुरा विचार माना जाता है जो केवल जावा संगतता के लिए किया जाता था।

scala> class Test { def test { this.synchronized { } } } 
defined class Test 

scala> :javap -c Test 
Compiled from "<console>" 
public class Test extends java.lang.Object implements scala.ScalaObject{ 
public void test(); 
    Code: 
    0: aload_0 
    1: dup 
    2: astore_1 
    3: monitorenter 
    4: getstatic #12; //Field scala/runtime/BoxedUnit.UNIT:Lscala/runtime/BoxedUnit; 
    7: pop 
    8: aload_1 
    9: monitorexit 
    10: return 
    11: aload_1 
    12: monitorexit 
    13: athrow 
    Exception table: 
    from to target type 
    4 10 11 any 
संबंधित मुद्दे