2011-08-05 11 views
6

एक लॉक हमेशा कोशिश/आखिरकार ब्लॉक के बाद होता है, क्यों?थ्रेड - क्यों प्रयास करें और आखिरकार

ReentrantReadWriteLock readWriteLockBitmap = new ReentrantReadWriteLock(); 
Lock read = readWriteLockBitmap.readLock(); 
Lock write = readWriteLockBitmap.writeLock(); 
int shared = 0; 

public void function1(){ 
    read.lock(); 
    try{ 
     //reading shared int 
    } 
    finally{ 
     read.unlock(); 
    } 
} 

public void function 2(){ 
    write.lock(); 
    try{ 
     //modify shared int 
    } 
    finally{ 
     write.unlock(); 
    } 
} 

क्यों इस कोशिश कर रहा/अंत में ब्लॉक और बस के रूप में इस कोड लिखने नहीं:

ReentrantReadWriteLock readWriteLockBitmap = new ReentrantReadWriteLock(); 
Lock read = readWriteLockBitmap.readLock(); 
Lock write = readWriteLockBitmap.writeLock(); 
int shared = 0; 

public void function1(){ 
    read.lock(); 
    //reading shared int 
    read.unlock(); 
} 

public void function 2(){ 
    write.lock(); 
    //modify shared int 
    write.unlock(); 
} 
+0

संभावित डुप्लिकेट [हम लॉक.लॉक और लॉक.नलॉक के लिए अंततः प्रयास कैसे करेंगे] (http: // stackoverflow।कॉम/प्रश्न/4664717/कैसे-होगा-हम-उपयोग-कोशिश-अंत-के-लॉक-लॉक-एंड-लॉक-अनलॉक) – JasonMArcher

उत्तर

6

मामले में कुछ भी में गलत हो जाता है (अपवाद फेंका आदि जा रहा है) क्या आप वाकई ताला है बनाना चाहते कोई फर्क नहीं पड़ता कि क्या। यह सिर्फ मानक अभ्यास है, भले ही इस मामले में तकनीकी रूप से अनावश्यक हो।

2

यह सुनिश्चित करने के लिए कि जो कुछ भी होता है, भले ही अपवाद फेंक दिया गया हो, फिर भी आप विधि छोड़ने से पहले लॉक स्ट्रीम को अनलॉक कर देंगे।

3

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

10

क्योंकि एक कोशिश/आखिरकार ब्लॉक यह गारंटी देने का एकमात्र तरीका है कि किसी अन्य पूर्ण होने के बाद कोड का एक खंड निष्पादित किया जाता है।

आप पूछ क्यों ऐसा नहीं:

public void function1(){ 
    read.lock(); 
    this.getSharedInt(); 
    read.unlock(); 
} 

जब this.getSharedInt() एक अपवाद फेंकता है तो क्या होगा? फिर आपकी read.unlock() लाइन निष्पादित नहीं की जाएगी, जिससे प्रोग्राम डेडलॉक हो जाएगा। निश्चित रूप से, यह को अपवाद फेंकने के लिए प्रमाणित नहीं हो सकता है, लेकिन जब आप फ़ाइल या डेटाबेस में उस साझा int को संग्रहीत करने के लिए प्रतिक्रिया करते हैं तो क्या होता है?

अंत में, भूलें कि आखिरकार त्रुटियों के लिए भी प्रयास करें, जिसे प्रोग्राम में लगभग किसी भी पंक्ति पर रनटाइम द्वारा फेंक दिया जा सकता है, भले ही फ़ंक्शन को किसी भी अपवाद को फेंकने की गारंटी न हो।

ध्यान दें कि यह कोड भी काम करेगा, लेकिन यह अपवाद निगलता है। finally का उपयोग करने के बजाय अपवाद को सामान्य रूप से प्रसारित करने की अनुमति देता है, जबकि सभी स्थितियों के तहत अभी भी अनलॉक हो रहा है।

public void function2(){ 
    read.lock(); 
    try { 
     this.getSharedInt(); 
    } catch(Throwable t) {} 
    read.unlock(); 
} 
+1

+1 "मैं एक बुरे आदमी" के लिए रीफैक्टरिंग बिट –

4

तो कुछ इस तरह नहीं होता है कि:

private static ReentrantReadWriteLock readWriteLockBitmap = new ReentrantReadWriteLock(); 
private static Lock read = readWriteLockBitmap.readLock(); 
private static Lock write = readWriteLockBitmap.writeLock(); 
private static int shared = 0; 

public static void function1() { 
    read.lock(); 
    somethingThatMightThrowAnException(); 
    read.unlock(); 
} 

private static void somethingThatMightThrowAnException() { 
    throw new RuntimeException("I'm a bad man."); 
} 

public static void function2() { 
    write.lock(); 
    //modify shared int 
    write.unlock(); 
} 

public static void main(String[] args) { 
    try { 
     function1(); 
    } catch (Exception e) { 
     System.out.println("Got an exception, but so what?"); 
    } 
    function2(); 
} 
+1

+1 के लिए +1। : डी – jdmichal

0

http://www.google.co.uk/#sclient=psy&hl=en&q=java+Why+a+Lock+has+to+be+followed+by+try+and+finally+%3F

पहले हिट है:

में: http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/locks/Lock.html

महत्वपूर्ण हिस्सा का हवाला देते हुए अधिकांश मामले, निम्नलिखित मुहावरा इस्तेमाल किया जाना चाहिए:

Lock l = ...; 
l.lock(); 
try { 
    // access the resource protected by this lock 
} finally { 
    l.unlock(); 
} 

जब लॉक करने और अनलॉक अलग-अलग दायरों में पाए जाते हैं, देखभाल सुनिश्चित करना है कि सभी कोड है कि जब तक ताला आयोजित किया जाता है निष्पादित किया जाता है से कोशिश अंत में या कोशिश सुरक्षित है लिया जाना चाहिए यह सुनिश्चित करने के लिए कि लॉक आवश्यक होने पर जारी किया गया है।

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