क्या Random
कई धागों के बीच वर्ग का एक उदाहरण साझा करना मान्य है ? और nextInt(int)
विशेष रूप से कई थ्रेड से कॉल करने के लिए ?
java.util.concurrent.ThreadLocalRandom
।
क्या Random
कई धागों के बीच वर्ग का एक उदाहरण साझा करना मान्य है ? और nextInt(int)
विशेष रूप से कई थ्रेड से कॉल करने के लिए ?
java.util.concurrent.ThreadLocalRandom
।
जवाबों:
यह कई अर्थों में उपयोग किए जाने पर रैंडम नंबर जेनरेट करेगा।
सन / ओरेकल जेवीएम कार्यान्वयन धागे के पार स्थिरता में सुधार के लिए बीज के रूप में सिंक्रनाइज़ और एटॉमिकलॉन्ग का उपयोग करता है। लेकिन यह प्रलेखन में सभी प्लेटफार्मों के लिए ग्वारेंटेड प्रतीत नहीं होता है।
मुझे आपके कार्यक्रम को ऐसी गारंटी की आवश्यकता नहीं है, खासकर जब आप उस आदेश को निर्धारित नहीं कर सकते जिसमें nextInt()
कहा जाएगा।
यह धागा सुरक्षित है, हालांकि यह हमेशा नहीं था।
अधिक जानकारी के लिए http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6362070 देखें ।
प्रलेखन की रिकॉर्डिंग , Math.random () यह गारंटी देता है कि यह कई थ्रेड्स द्वारा उपयोग के लिए सुरक्षित है। लेकिन रैंडम वर्ग नहीं करता है। मुझे लगता है कि फिर आपको खुद को सिंक्रनाइज़ करना होगा।
हां, रैंडम थ्रेड सेफ है। nextInt()
विधि संरक्षित कॉल next(int)
तरीका है जिसके उपयोग करता है AtomicLong seed, nextseed
(परमाणु लंबे) एक अगले बीज उत्पन्न करने के लिए। AtomicLong
बीज उत्पादन पर धागा-सुरक्षा के लिए उपयोग किया जाता है।
जैसा कि कहा गया है, यह थ्रेड सेव है, लेकिन इस लेख (लिंक डेड) के java.util.concurrent.ThreadLocalRandom
अनुसार उपयोग करना समझदारी हो सकती है । ThreadLocalRandom भी रैंडम का एक उपवर्ग है, इसलिए यह पीछे की ओर संगत है।
लेख की तुलना में अलग रैंडम कक्षाओं के परिणामों की रूपरेखा लिंक कर दिया है:
java.util.Random
,java.util.concurrent.ThreadLocalRandom
औरjava.lang.ThreadLocal<java.util.Random>
। परिणामों से पता चला, कि थ्रेडलोक-रैंडम का उपयोग सबसे अधिक प्रभावी है, इसके बाद थ्रेडलोकल और सबसे खराब रैंडम प्रदर्शन।
कोई कारण नहीं है कि कई धागे सभी एक ही यादृच्छिक का उपयोग नहीं कर सकते हैं। हालांकि, चूंकि वर्ग स्पष्ट रूप से धागा-सुरक्षित नहीं है और बीज के माध्यम से छद्म यादृच्छिक संख्याओं के अनुक्रम को बनाए रखता है। कई धागे एक ही यादृच्छिक संख्या के साथ समाप्त हो सकते हैं। बेहतर होगा कि प्रत्येक धागे के लिए कई रैंडम बनाएं और उन्हें अलग तरीके से बीज दें।
संपादित करें : मैंने अभी देखा है कि सूर्य कार्यान्वयन एटॉमिकलॉन्ग का उपयोग करता है इसलिए मुझे लगता है कि थ्रेड-सुरक्षित है (जैसा कि पीटर लॉरी (+1) ने भी नोट किया है)।
EDIT2 : OpenJDK बीज के लिए AtomicLong का भी उपयोग करता है। जैसा कि अन्य लोगों ने कहा है कि इस पर भरोसा करना अभी भी अच्छा नहीं है।
यहां बताया गया है कि कैसे मैं इस समस्या से निपटता हूं कि रैंडम परमाणु चर का उपयोग करता है। यह अभी भी बेतरतीब ढंग से टकरा सकता 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)
हिस्सा महत्वपूर्ण है?
(24*60*60*1000)
कि आईडी के साथ एक धागा इतना था 12
पर xxxxxxxxxx045
मिली सेकंड वरीयता प्राप्त नहीं हुआ एक धागा रूप में एक ही 22
में xxxxxxxxxx035
मिली सेकंड। हालाँकि, मेरे पास यह मानने का कोई अच्छा कारण नहीं है कि थ्रेड आईडी वृद्धिशील हैं, और यह सोचने का कोई अच्छा कारण नहीं है कि मैं आज की तुलना में कल अधिक यादृच्छिक समय पर थ्रेड बना रहा हूं। मैंने अब alg को सरल बनाया और कमी को पहचानने के लिए विवरण को अद्यतन किया।
Random
वर्ग एक से अधिक थ्रेड में प्रयोग की जाने वाली एक उदाहरण के लिए सेट नहीं है। बेशक, अगर आपने ऐसा किया है, तो संभावना है कि आप अन-प्रेडिक्टेबल होने और रैंडम नंबर के करीब आने की संभावना बढ़ा देंगे । लेकिन चूंकि यह एक छद्म यादृच्छिक जनरेटर है, इसलिए मैं यह नहीं देख सकता कि आपको एक उदाहरण साझा करने की आवश्यकता क्यों होगी। क्या अधिक विशिष्ट आवश्यकता है?