आपके पास समस्या यह है कि आप कोड को अनुकूलित करने के लिए पर्याप्त लंबे समय तक इंतजार नहीं कर रहे हैं और मूल्य कैश किया जाना चाहिए।
जब x86_64 सिस्टम पर कोई थ्रेड पहली बार मान पढ़ता है, तो उसे थ्रेड सुरक्षित प्रति प्राप्त होती है। इसके बाद के बाद में परिवर्तन यह देखने में असफल हो सकता है। यह अन्य CPUs पर मामला नहीं हो सकता है।
यदि आप इसे आजमाते हैं तो आप देख सकते हैं कि प्रत्येक थ्रेड अपने स्थानीय मूल्य से फंस गया है।
public class RequiresVolatileMain {
static volatile boolean value;
public static void main(String... args) {
new Thread(new MyRunnable(true), "Sets true").start();
new Thread(new MyRunnable(false), "Sets false").start();
}
private static class MyRunnable implements Runnable {
private final boolean target;
private MyRunnable(boolean target) {
this.target = target;
}
@Override
public void run() {
int count = 0;
boolean logged = false;
while (true) {
if (value != target) {
value = target;
count = 0;
if (!logged)
System.out.println(Thread.currentThread().getName() + ": reset value=" + value);
} else if (++count % 1000000000 == 0) {
System.out.println(Thread.currentThread().getName() + ": value=" + value + " target=" + target);
logged = true;
}
}
}
}
}
निम्नलिखित को प्रिंट करता है जो उसके मूल्य को फ़्लिप करता है, लेकिन अटक जाता है।
Sets true: reset value=true
Sets false: reset value=false
...
Sets true: reset value=true
Sets false: reset value=false
Sets true: value=false target=true
Sets false: value=true target=false
....
Sets true: value=false target=true
Sets false: value=true target=false
अगर मैं -XX:+PrintCompilation
इस स्विच समय के बारे में होता है जोड़ने जैसा कि आप देख
1705 1 % RequiresVolatileMain$MyRunnable::run @ -2 (129 bytes) made not entrant
1705 2 % RequiresVolatileMain$MyRunnable::run @ 4 (129 bytes)
कौन सा कोड निवासी संकलित किया गया है पता चलता है एक तरह से जो सुरक्षित थ्रेड नहीं है।
यदि आप मूल्य volatile
आप इसे मूल्य बेहद flipping दिखाई देता है (या जब तक मुझे मिल ऊब)
संपादित करें: क्या इस परीक्षण करता है, जब यह मान का पता लगाता है कि धागे लक्ष्य मान नहीं है, तो यह मान निर्धारित करता है। अर्थात। थ्रेड 0 true
पर सेट करता है और थ्रेड 1 सेट false
पर सेट होता है जब दो थ्रेड फ़ील्ड को सही तरीके से साझा कर रहे होते हैं तो वे एक दूसरे को बदलते हैं और मान लगातार सत्य और झूठे के बीच फ़्लिप करता है।
अस्थिर बिना इस विफल रहता है और प्रत्येक थ्रेड केवल अपने स्वयं के मूल्य को देखता है, तो वे दोनों दोनों मूल्य और धागा 0 true
देख सकते हैं और धागा 1 एक ही क्षेत्र के लिए false
देखता है बदल रहा है।
लघु जवाब नहीं। लेकिन क्या आपको वास्तव में यह जांचने की ज़रूरत है कि किसी ने आपको बताया और अच्छे कारण दिए जाने के बाद छत से कूदना खतरनाक है या नहीं? – Voo
2 कोर के साथ एक कंप्यूटर का उपयोग करें। –
@ वू ... आप किस पृथ्वी पर बात कर रहे हैं? –