2013-04-14 7 views
28

मेरे पास सुपरक्लास Point और synchronized विधि draw() है। Point के उप-वर्गों में synchronized का उत्तराधिकारी होगा यदि मैं उनमें से draw() विधि को ओवरराइड करता हूं या मुझे हमेशा इसे लिखना है?जावा में विरासत में सिंक्रनाइज़ किया गया है?

+0

एक तुल्यकालन की [ओवरराइड करना संभव डुप्लिकेट था विधि] (http://stackoverflow.com/questions/10173345/overriding-a-synchronized-method) – Raedwald

उत्तर

28

नहीं, आपको हमेशा synchronized लिखना होगा। यदि आप सुपर क्लास की सिंक्रनाइज़ विधि को कॉल करते हैं तो यह निश्चित रूप से एक सिंक्रनाइज़ कॉल होगा। synchronized विधि हस्ताक्षर का हिस्सा नहीं है।

डॉग ली, जावा थ्रेडिंग बॉस (या तो) से विस्तृत विवरण के लिए http://gee.cs.oswego.edu/dl/cpj/mechanics.html देखें।

+2

शायद एक विवरण स्पष्ट करें: चाहे दिया गया विधि कॉल सिंक्रनाइज़ किया गया हो, उस वस्तु के गतिशील प्रकार पर निर्भर करता है जिसे स्थिर कहा जाता है, स्थिर प्रकार नहीं। यही है, यदि 'व्युत्पन्न' में 'foo()' 'सिंक्रनाइज़ किया गया है 'लेकिन' बेस' में नहीं है, और आप' बेस' चर 'पर' व्युत्पन्न 'असाइन करते हैं और उस पर' foo() 'कहते हैं, तो कॉल सिंक्रनाइज़ किया जाना चाहिए। यह बिंदु भाषा spec के 8.4.3.6 में अंतर्निहित है (जो कहता है कि 'सिंक्रनाइज़' विधि उस विधि के भीतर 'सिंक्रनाइज़ किए गए' कथन के समतुल्य है), लेकिन मुझे इसे कहीं और वर्तनी नहीं मिली। रननेबल डेमो [यहां] (http://runnable.com/U4zBThIj5WNju2g2/)। – mrec

4

आपकी ओवर्रिडेन विधि अब सिंक्रनाइज़ नहीं की जाएगी यदि आप इसे ओवरराइड करते हैं और synchronized हटाते हैं। इसे here और here

+1

आपके उद्धरणों में से कोई भी एक मानक संदर्भ नहीं है। – EJP

10

तुम खुद जांच कर सकते हैं इस लिख कर:

public class Shape { 

    protected int sum = 0; 

    public synchronized void add(int x) { 
     sum += x; 
    } 
} 


public class Point extends Shape{ 

    public void add(int x) { 
     sum += x; 
    } 

    public int getSum() { 
     return sum; 
    } 
} 

और परीक्षण वर्ग

public class TestShapes { 

    public final static int ITERATIONS = 100000; 

    public static void main(String[] args) throws InterruptedException { 

     final Point p = new Point(); 

     Thread t1 = new Thread(){ 
      @Override 
      public void run() { 

       for(int i=0; i< ITERATIONS; i++){ 
        p.add(1); 
       } 
      } 
     }; 

     Thread t2 = new Thread(){ 
      @Override 
      public void run() { 

       for(int i=0; i< ITERATIONS; i++){ 
        p.add(1); 
       } 
      } 
     }; 

     t1.start(); 
     t2.start(); 

     t1.join(); 
     t2.join(); 


     System.out.println(p.getSum()); // should equal 200000 

    } 
} 

मेरी मशीन पर यह 137,099 बजाय 200000.

+2

परीक्षण करने का आसान तरीका ['थ्रेड.होल्ड्स लॉक (यह); '] पर परीक्षण करना होगा; http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#holdsLock% 28java.lang.Object% 29) ओवरराइड विधि में –

+4

प्रश्न का उत्तर नहीं देता है। सिंक्रनाइज़ेशन के अलावा किसी अन्य चीज़ के कारण टेस्ट कोड बस एक बग या एक समय विसंगति का पर्दाफाश कर सकता है। जवाब भाषा विनिर्देश में पाया जाना है। – EJP

+0

@EJP पहले मैंने सोचा कि आप गलत थे। तब मुझे एहसास हुआ कि आप वास्तव में सही थे, बल्कि निराशावादी ... – Timo

संबंधित मुद्दे