क्या रैंडम क्लास थ्रेड सुरक्षित है?


110

क्या Randomकई धागों के बीच वर्ग का एक उदाहरण साझा करना मान्य है ? और nextInt(int)विशेष रूप से कई थ्रेड से कॉल करने के लिए ?


@ बाला आर, नहीं, हम C # की रैंडम ऑब्जेक्ट के बारे में बात नहीं कर रहे हैं, लेकिन जावा की।
बुहके सिंडी

उफ़। क्षमा करें, वह हिस्सा छूट गया।
बाला आर

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

14
आगे के पाठकों के लिए: 1.7 नाम वाला एक नया वर्ग है java.util.concurrent.ThreadLocalRandom
जिन क्‍वोन

जवाबों:


66

यह कई अर्थों में उपयोग किए जाने पर रैंडम नंबर जेनरेट करेगा।

सन / ओरेकल जेवीएम कार्यान्वयन धागे के पार स्थिरता में सुधार के लिए बीज के रूप में सिंक्रनाइज़ और एटॉमिकलॉन्ग का उपयोग करता है। लेकिन यह प्रलेखन में सभी प्लेटफार्मों के लिए ग्वारेंटेड प्रतीत नहीं होता है।

मुझे आपके कार्यक्रम को ऐसी गारंटी की आवश्यकता नहीं है, खासकर जब आप उस आदेश को निर्धारित नहीं कर सकते जिसमें nextInt()कहा जाएगा।


69
जावा 7 डॉक्स में एक गारंटी जोड़ी गई है: "java.util.Random के उदाहरण थ्रेडसेफ़ हैं।" docs.oracle.com/javase/7/docs/api/java/util/Random.html
मैट आर


8

प्रलेखन की रिकॉर्डिंग , Math.random () यह गारंटी देता है कि यह कई थ्रेड्स द्वारा उपयोग के लिए सुरक्षित है। लेकिन रैंडम वर्ग नहीं करता है। मुझे लगता है कि फिर आपको खुद को सिंक्रनाइज़ करना होगा।


7

हां, रैंडम थ्रेड सेफ है। nextInt()विधि संरक्षित कॉल next(int)तरीका है जिसके उपयोग करता है AtomicLong seed, nextseed(परमाणु लंबे) एक अगले बीज उत्पन्न करने के लिए। AtomicLongबीज उत्पादन पर धागा-सुरक्षा के लिए उपयोग किया जाता है।


6

जैसा कि कहा गया है, यह थ्रेड सेव है, लेकिन इस लेख (लिंक डेड) के java.util.concurrent.ThreadLocalRandomअनुसार उपयोग करना समझदारी हो सकती है । ThreadLocalRandom भी रैंडम का एक उपवर्ग है, इसलिए यह पीछे की ओर संगत है।

लेख की तुलना में अलग रैंडम कक्षाओं के परिणामों की रूपरेखा लिंक कर दिया है: java.util.Random, java.util.concurrent.ThreadLocalRandom और java.lang.ThreadLocal<java.util.Random>। परिणामों से पता चला, कि थ्रेडलोक-रैंडम का उपयोग सबसे अधिक प्रभावी है, इसके बाद थ्रेडलोकल और सबसे खराब रैंडम प्रदर्शन।


4

कोई कारण नहीं है कि कई धागे सभी एक ही यादृच्छिक का उपयोग नहीं कर सकते हैं। हालांकि, चूंकि वर्ग स्पष्ट रूप से धागा-सुरक्षित नहीं है और बीज के माध्यम से छद्म यादृच्छिक संख्याओं के अनुक्रम को बनाए रखता है। कई धागे एक ही यादृच्छिक संख्या के साथ समाप्त हो सकते हैं। बेहतर होगा कि प्रत्येक धागे के लिए कई रैंडम बनाएं और उन्हें अलग तरीके से बीज दें।

संपादित करें : मैंने अभी देखा है कि सूर्य कार्यान्वयन एटॉमिकलॉन्ग का उपयोग करता है इसलिए मुझे लगता है कि थ्रेड-सुरक्षित है (जैसा कि पीटर लॉरी (+1) ने भी नोट किया है)।

EDIT2 : OpenJDK बीज के लिए AtomicLong का भी उपयोग करता है। जैसा कि अन्य लोगों ने कहा है कि इस पर भरोसा करना अभी भी अच्छा नहीं है।


3

यहां बताया गया है कि कैसे मैं इस समस्या से निपटता हूं कि रैंडम परमाणु चर का उपयोग करता है। यह अभी भी बेतरतीब ढंग से टकरा सकता currentTime * thread idहै अगर भविष्य में कुछ समय बराबर हो, लेकिन मेरी जरूरतों के लिए यह काफी दुर्लभ है। टकराव की संभावना से वास्तव में बचने के लिए, आप एक अद्वितीय घड़ी टाइमस्टैम्प के लिए प्रत्येक अनुरोध प्रतीक्षा कर सकते हैं।

/**
 * Thread-specific random number generators. Each is seeded with the thread
 * ID, so the sequence of pseudo-random numbers are unique between threads.
 */
private static ThreadLocal<Random> random = new ThreadLocal<Random>() {
    @Override
    protected Random initialValue() {
        return new Random(
            System.currentTimeMillis() *
            Thread.currentThread().getId());
    }
};

यूपी! क्यू: (24*60*60*1000)हिस्सा महत्वपूर्ण है?
जिन क्वॉन

1
हाँ, यह एक गंदा फिक्स था। (24*60*60*1000)कि आईडी के साथ एक धागा इतना था 12पर xxxxxxxxxx045मिली सेकंड वरीयता प्राप्त नहीं हुआ एक धागा रूप में एक ही 22में xxxxxxxxxx035मिली सेकंड। हालाँकि, मेरे पास यह मानने का कोई अच्छा कारण नहीं है कि थ्रेड आईडी वृद्धिशील हैं, और यह सोचने का कोई अच्छा कारण नहीं है कि मैं आज की तुलना में कल अधिक यादृच्छिक समय पर थ्रेड बना रहा हूं। मैंने अब alg को सरल बनाया और कमी को पहचानने के लिए विवरण को अद्यतन किया।
रयान

0

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.