2010-12-04 22 views
10

एक बेहद समवर्ती जावा प्रोग्राम में और यह सोचते हैं कि मेरी तरीकों को सही ढंग से लिखा जाता है और सही ढंग से सिंक्रनाइज़, मैं कैसे निर्धारित करने के लिए है जो के बारे में सोच रहा हूँ बेहतर:तुल्यकालन की लागत

void synchronized something() { 
    ... 
} 

या

void something() { 
    synchronized(this) { 
     ... 
    } 
    // here do stuff no requiring synchronization 
    . 
    . // do computation 'A' 
    . 
    synchronized(this) { 
     ... 
    } 
    // here do other stuff no requiring synchronization 
    . 
    . // do computation 'B' 
    . 
    synchronized(this) { 
     ... 
    } 
} 

अब मुझे एहसास है कि यदि गणना 'ए' और 'बी' में काफी समय लगता है, तो दूसरा संस्करण स्पष्ट रूप से बेहतर है।

मेरा प्रश्न, हालांकि, यह है कि आप किस बिंदु पर जानते हैं कि दूसरा संस्करण अधिक कुशल है?

क्या दूसरा संस्करण हमेशा तेज़ है या क्या लॉक को कई बार प्राप्त/रिलीज़ करने के बारे में छिपी हुई लागत है?

क्या होगा अगर मेरा गणना 'ए' बस की तरह कुछ तुच्छ है:

s.getString().substring(0, 2).toLowerCase(); 
+0

ध्यान दें कि मेरे पास "जावा कंसुरेंसी इन प्रैक्टिस" * :) – SyntaxT3rr0r

उत्तर

8

हाँ, synchronized समय खर्च होता है। यदि वास्तविक गणना सरल हैं और यह एक लूप के अंदर है, तो वास्तविक गणनाओं की तुलना में बहुत लागत है।

इस उदाहरण देखें: http://ideone.com/zgpB7

  • इनर हिस्सा सिंक्रनाइज़: लगभग 0.025s
  • पूरे पाश सिंक्रनाइज़: कम से कम 0.001s

निर्धारित करने के लिए जो एक अपने कार्यक्रम के लिए बेहतर है, चलो यह सामान करता है और देखो कि यह किस समय तेज़ है।

+0

+1 की मेरी प्रतिलिपि है ... मैं काफी चौंक गया हूं :) मुझे यकीन था कि आंखों की तुलना में इससे कहीं अधिक था :) – SyntaxT3rr0r

+5

दूसरी बात यह है कि वह उदाहरण दिखाता है कि 1,000,000 synchrnonization ताले 0.024 सेकंड लेते हैं। तो जब तक कि आप लाखों बार पुनरावृत्त नहीं कर रहे हैं, या आपके पास धागे के बीच प्रबल संसाधन विवाद है, सिंक्रनाइज़ेशन स्वयं वास्तव में धीमा नहीं है। (स्पष्ट रूप से 0.000000024 सेकंड प्रति लॉक जो भी मशीन उन उदाहरणों पर चला गया)। – Gus

+1

मुझे लगता है कि बड़े सिंक्रनाइज़ किए गए ब्लॉक का उपयोग करने के लिए सबसे बड़ी हिट समरूपता का नुकसान है। अचानक आपके एकाधिक प्रोसेसर मदद नहीं करते हैं। यदि आपके पास अन्य थ्रेड हैं जो लॉक पर इंतजार नहीं कर रहे हैं तो यह – Cruncher

2

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

आवश्यक से अधिक समय तक लॉक रखना, अन्य धागे को धीमा कर सकता है। उन्हें बैठकर इंतजार करना पड़ता है जब आप काम कर रहे होते हैं जो उस काम में हस्तक्षेप नहीं करेंगे जो वे करना चाहते हैं। यदि यह ऐसी स्थिति है जहां मिलीसेकंड वास्तव में आपके लिए महत्वपूर्ण हैं, तो आपको यह देखने के लिए एक प्रोफाइलर का उपयोग करना चाहिए कि आपकी स्थिति सबसे अच्छी तरह से क्या काम करती है। मल्टी-थ्रेडिंग ऑप्टिमाइज़ेशन उन परिस्थितियों में से एक है जहां "सर्वोत्तम प्रथाएं" होती हैं जो आम तौर पर सच होती हैं, लेकिन आपको नियम नहीं मिलेंगे जो सभी स्थितियों में काम करता है। यदि आपको उस ग्रैन्युलरिटी की ज़रूरत है, तो आपको इसका परीक्षण करना चाहिए और देखना चाहिए।

1

क्या "सही ढंग से लिखा गया" और "सही सिंक्रनाइज़" का अर्थ है कि बहु-सिंक्रनाइज़ किए गए केस में कोड-सेक्शन के बीच कोई निर्भरता नहीं है? यदि निर्भरताएं हैं, तो यह हो सकता है कि बहु-सिंक्रनाइज़ किए गए मामले के परिणामस्वरूप एक आविष्कार का उल्लंघन हो सकता है। एक और तरीका रखो, क्या आप गारंटी दे सकते हैं कि बहु-सिंक्रनाइज़ किए गए केस के निष्पादन से कुछ ऑब्जेक्ट किसी अमान्य स्थिति में नहीं होगा? यदि नहीं, तो सिंगल सिंक्रनाइज़ केस बेहतर हो सकता है।

+0

yup, यह गारंटी है। यह वास्तव में मेरे प्रश्न का परिसर है :) IOW, आप मेरे प्रश्न को पूरी तरह से सैद्धांतिक प्रश्न के रूप में देख सकते हैं :) – SyntaxT3rr0r

+1

@SpoonBender: उस स्थिति में, दो समाधानों का सापेक्ष प्रदर्शन उपलब्ध CPU-s की संख्या पर निर्भर हो सकता है। –

+0

@SteveEmmerson या धागे और सीपीयू की संख्या के बीच अनुपात का एक समारोह। – Cruncher

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