2012-10-13 15 views
7

currentPrice और 100 के बीच अधिक संख्या होने का दिए गए दो विकल्पों ...क्या टर्नरी ऑपरेटर (? :) थ्रेड सी # में सुरक्षित है?

int price = currentPrice > 100 ? currentPrice : 100 

int price = Math.Max(currentPrice, 100) 

मैं इस सवाल उठाया क्योंकि मैं एक संदर्भ में, जहां currentPrice चर अन्य थ्रेड द्वारा संपादित किया जा सकता है के बारे में सोच रहा था पर विचार करें।

पहले मामले में ... price100 से कम मान प्राप्त कर सकता है?

मैं निम्नलिखित के बारे में सोच रहा हूँ:

if (currentPrice > 100) { 
    //currentPrice is edited here. 
    price = currentPrice; 
} 

उत्तर

8

यह threadsafe नहीं है।

?: बस सामान्य if के लिए शॉर्टकट है, इसलिए आपका if नमूना ? एक के बराबर है - अगर वहाँ इस कोड को बाहर कोई ताला है आप कीमत 100 से कम हो सकता है।

+0

कुछ मिनटों में विपरीत जवाब? : डी – dotNETbeginner

+0

@ डॉटनेटबेगिनर :) अच्छा अवलोकन। जब मैंने अपना पहला जवाब पढ़ा तो मैं मुझे -10 भी देना चाहता था। –

3

सिद्धांत रूप में, वर्तमानप्रिस दो बार पढ़ा जाता है। एक बार तुलना के लिए, एक बार असाइनमेंट के लिए।

प्रैक्टिस में, कंपाइलर चर के उपयोग को कैश कर सकता है। मैं सी # के बारे में लेकिन C++ 86 पर पता नहीं है:

MOV AX, [currentPrice] 
MOV BX, 100 ;cache the immediate 
CMP AX, BX 
JLE $1  ;if(currentPrice > 100){ 
MOV AX, BX 
$1:   ;} 
MOV [BP+price], AX ;price is on the stack. 

ही लोड एक बार अनुकूलन जावा बाईटकोड में क्या होता है जब तक कि currentPrice अस्थिर घोषित किया जाता है।

तो, सिद्धांत रूप में, यह हो सकता है। व्यावहारिक रूप से, अधिकांश प्लेटफॉर्म पर, यह नहीं होगा, लेकिन आप उस पर भरोसा नहीं कर सकते हैं।

3

सी # में कोई विशेषज्ञ नहीं है, लेकिन यहां तक ​​कि var ++ थ्रेड सेव नहीं है, क्योंकि असेंबली में रजिस्टर से पढ़ने/लिखने से अनुवाद किया जा सकता है।

टर्नरी ऑपरेटर कहीं अधिक जटिल है। इसमें 3 भाग हैं, जबकि प्रत्येक भाग अंतहीन रूप से बड़ा हो सकता है (उदा। कुछ फ़ंक्शन पर कॉल करें)। इसलिए, यह निष्कर्ष निकालना बहुत आसान है कि टर्नरी ऑपरेटर थ्रेड सुरक्षित नहीं है।

+1

+1; मुझे डर है कि x86 आपको स्मृति स्थान को 'इंक' करने की अनुमति नहीं देगा, इसलिए इसे रजिस्ट्री/वृद्धि/मेमोरी कॉम्बो में स्थानांतरित करने के लिए एक कदम के रूप में अनुवादित किया जाएगा। –

1

जैसा कि दूसरों ने कहा है, इसे कैश किया जा सकता है लेकिन भाषा की आवश्यकता नहीं है।

यदि आप लॉक-फ्री थ्रेडसेफ असाइनमेंट की आवश्यकता है तो आप Interlocked.CompareExchange का उपयोग कर सकते हैं। लेकिन उदाहरण दिया गया, मैं एक और अधिक मोटे अनाज लॉकिंग रणनीति के लिए जाना होगा।

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