2009-02-23 7 views
155

यदि मेरे पास स्थैतिक विधियों वाला उपयोग वर्ग है जो मूल डेटा पहुंच को पूरा करने के लिए हाइबरनेट फ़ंक्शन को कॉल करेगा। मैं सोच रहा हूं कि विधि बनाने के लिए synchronized थ्रेड-सुरक्षा सुनिश्चित करने का सही दृष्टिकोण है।सिंक्रनाइज़ किए गए स्थिर तरीके जावा में कैसे काम करते हैं?

मैं चाहता हूं कि यह उसी डीबी इंस्टेंस में जानकारी तक पहुंच को रोक सके। हालांकि, अब मुझे यकीन है कि यदि निम्न कोड getObjectById को सभी वर्गों के लिए बुलाया जा रहा है, तो इसे किसी विशेष वर्ग द्वारा बुलाया जा रहा है।

public class Utils { 
    public static synchronized Object getObjectById (Class objclass, Long id) { 
      // call hibernate class 
     Session session = new Configuration().configure().buildSessionFactory().openSession(); 
     Object obj = session.load(objclass, id); 
     session.close(); 
     return obj; 
    } 

    // other static methods 
} 

उत्तर

127

से निपटने में पूरी तरह से सक्षम है द्वारा एक स्थिर पद्धति पर सिंक्रनाइज़ का उपयोग कर ताला आप synchronize the class methods and attributes (के रूप में उदाहरण के तरीकों का विरोध किया और विशेषताएँ)

तो अपने धारणा है जाएगा सही बात।

मुझे आश्चर्य है कि विधि सिंक्रनाइज़ करने के लिए थ्रेड-सुरक्षा सुनिश्चित करने का सही दृष्टिकोण है या नहीं।

वास्तव में नहीं। आपको उस काम को अपने आरडीबीएमएस के बजाय करना चाहिए। वे इस तरह के सामान पर अच्छे हैं।

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

इस परिदृश्य की कल्पना कीजिए:

ग्राहक ए और बी प्रयास तालिका टी के रिकॉर्ड एक्स में अलग अलग जानकारी डालने के लिए

अपने दृष्टिकोण के साथ

केवल एक चीज आप हो रही है यकीन है कि एक बनाने के लिए है कहा जाता है दूसरी तरफ, जब यह डीबी में होगा, क्योंकि आरडीबीएमएस उन्हें एक ही समय में बी से आधा जानकारी डालने से रोक देगा। नतीजा वही होगा लेकिन केवल 5 गुना (या अधिक) धीमा होगा।

शायद हाइबरनेट दस्तावेज़ों में "Transactions and Concurrency" अध्याय को देखने के लिए बेहतर हो सकता है। ज्यादातर बार जिन समस्याओं को आप हल करने का प्रयास कर रहे हैं, उन्हें पहले से ही हल किया गया है और एक बेहतर तरीका है।

+1

बहुत उपयोगी जवाब! धन्यवाद! तो हाइबरनेट "आशावादी लॉकिंग" द्वारा cnocurrency का ख्याल रखता है। फिर किसी भी डेटा-पहुंच समेकन को हल करने के लिए "सिंक्रनाइज़" विधियों का उपयोग करने की आवश्यकता नहीं है ?? डेटाबेस में डेटा संग्रहीत नहीं होने पर केवल "सिंक्रनाइज़" विधियों का उपयोग करें ?? ..क्या आप उनका इस्तेमाल करते हैं ?? – tomato

+1

1) मुझे लगता है कि निराशावादी लॉकिंग का उपयोग करने के कुछ साधन भी हैं। 2) नहीं, आरडीबीएमएस वह काम कर सकता है। 3) यदि डेटा एक ही समय में एकाधिक धागे द्वारा उपयोग किया जाता है। 4) सिंक्रनाइज़ेशन तब उपयोगी होता है जब दो थ्रेड को डेटा साझा करना होता है। अगर उन्हें जरूरत नहीं है, तो बहुत बेहतर! – OscarRyz

+7

कोई भी फास्ट फूड रेस्तरां मल्टीथ्रेड का उपयोग करता है। एक थ्रेड आपको ऑर्डर लेता है और इसे तैयार करने के लिए एक और थ्रेड का उपयोग करता है, और अगले ग्राहक के साथ जारी रहता है। सिंक्रनाइज़ेशन पॉइंट केवल तभी काम करता है जब वे जानना चाहते हैं कि क्या तैयार करना है। एक मॉडल के बाद जो वास्तव में जीवन को सरल बनाता है। – OscarRyz

16

स्टेटिक विधियां क्लास को लॉक करने के लिए ऑब्जेक्ट के रूप में उपयोग करती हैं, जो आपके उदाहरण के लिए Utils.class है। तो हाँ, यह ठीक है।

2

यदि यह आपके डेटाबेस में डेटा के साथ कुछ करने के लिए है, तो डेटाबेस अलगाव लॉकिंग का उपयोग क्यों नहीं करें?

+0

मेरे पास कोई डेटाबेस पृष्ठभूमि नहीं है। अब मुझे पता है!! इस पर ध्यान दिलाने के लिए धन्यवाद! :) – tomato

2

अपने प्रश्न का उत्तर देने के लिए, हाँ यह करता है: आपकी synchronized विधि एक समय में एक से अधिक धागे द्वारा निष्पादित नहीं की जा सकती है।

9

आप यह क्यों लागू करना चाहते हैं कि केवल एक ही धागा किसी भी समय डीबी तक पहुंच सके?

किसी भी आवश्यक लॉकिंग को लागू करने के लिए यह डेटाबेस ड्राइवर का काम है, मानते हैं कि Connection केवल एक थ्रेड द्वारा उपयोग किया जाता है!

सबसे अधिक संभावना, अपने डेटाबेस एकाधिक, समानांतर पहुँच

+0

मैं शर्त लगा रहा हूं कि यह कुछ लेनदेन संबंधी मुद्दे के लिए एक समाधान है। यानी, समाधान वास्तविक समस्या को हल नहीं करता –

+1

मुझे यह नहीं पता था .... मैंने सोचा कि मुझे इसे मैन्युअल रूप से कार्यान्वित करना होगा। इस पर ध्यान दिलाने के लिए धन्यवाद! :) – tomato

205

अधिक आम तौर पर प्रश्न को हल करने के लिए ...

ध्यान रखें कि तरीकों पर सिंक्रनाइज़ का उपयोग वास्तव में सिर्फ आशुलिपि (मान वर्ग SomeClass है):

synchronized static void foo() { 
    ... 
} 

रूप

static void foo() { 
    synchronized(SomeClass.class) { 
     ... 
    } 
} 

और

synchronized void foo() { 
    ... 
} 

है एक ही है

के समान
void foo() { 
    synchronized(this) { 
     ... 
    } 
} 

आप किसी ऑब्जेक्ट को लॉक के रूप में उपयोग कर सकते हैं। आप स्थिर तरीकों के सबसेट लॉक करना चाहते हैं, तो आप

class SomeClass { 
    private static final Object LOCK_1 = new Object() {}; 
    private static final Object LOCK_2 = new Object() {}; 
    static void foo() { 
     synchronized(LOCK_1) {...} 
    } 
    static void fee() { 
     synchronized(LOCK_1) {...} 
    } 
    static void fie() { 
     synchronized(LOCK_2) {...} 
    } 
    static void fo() { 
     synchronized(LOCK_2) {...} 
    } 
} 

+7

उन शीर्ष 4 कोड ब्लॉक सोने हैं। ठीक वही जो मेरे द्वारा खोजा जा रहा था। धन्यवाद। –

+0

क्या यह सही है कि यदि मैं गैर स्थैतिक विधि पर एक स्थिर लॉक का उपयोग करता हूं, तो क्लास कुछ क्लास के किसी भी ऑब्जेक्ट को एक ही समय में ब्लॉक चलाने में सक्षम नहीं होगा? – Samuel

+2

@ सैमुएल - लगभग ... यह वस्तु उदाहरणों की तुलना में धागे के बारे में अधिक है। आप सही हैं कि SomeClass के अलग-अलग उदाहरण सभी एक ही लॉक/मॉनिटर का उपयोग करेंगे: एक Someclass.class ऑब्जेक्ट से जुड़ा हुआ है। तो यदि दो अलग-अलग धागे कुछ क्लास के दो अलग-अलग उदाहरणों को संसाधित कर रहे थे, तो वे दोनों एक ही समय में नहीं चल सके। हालांकि, अगर एक थ्रेड को कुछ क्लास के एक उदाहरण में विधि कहा जाता है, और उस विधि को अन्य उदाहरण में एक विधि कहा जाता है, तो कोई अवरोध नहीं होगा। –

13

static synchronized का मतलब है पर ताला पकड़े (गैर स्थिर तरीकों के लिए, आप ताले गैर स्थिर क्षेत्रों होना बनाना चाहते हैं) कर सकते हैं कक्षा का Class ऑब्जेक्ट जहां synchronized का अर्थ उस वर्ग की ऑब्जेक्ट पर लॉक रखना है। इसका अर्थ यह है कि, यदि आप थ्रेड (निष्पादन के) में एक गैर स्थैतिक सिंक्रनाइज़ विधि का उपयोग कर रहे हैं तो भी आप किसी अन्य थ्रेड का उपयोग करके एक स्थिर सिंक्रनाइज़ विधि का उपयोग कर सकते हैं।

तो, थ्रेड से अधिक समय पर किसी भी समय दो तरह की विधियों (या तो दो स्थैतिक या दो गैर स्थैतिक विधियों) तक पहुंच संभव नहीं है।

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