मेरी प्रयोगशाला में एक संवेदनशील ऑपरेशन आज पूरी तरह से गलत हो गया। इलेक्ट्रॉन माइक्रोस्कोप पर एक एक्ट्यूएटर अपनी सीमा पर चला गया, और घटनाओं की एक श्रृंखला के बाद मैंने $ 12 मिलियन उपकरण खो दिए। मैंने इसमें दोषपूर्ण मॉड्यूल में 40K से अधिक लाइनों को संकुचित किया है:
import java.util.*;
class A {
static Point currentPos = new Point(1,2);
static class Point {
int x;
int y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}
public static void main(String[] args) {
new Thread() {
void f(Point p) {
synchronized(this) {}
if (p.x+1 != p.y) {
System.out.println(p.x+" "+p.y);
System.exit(1);
}
}
@Override
public void run() {
while (currentPos == null);
while (true)
f(currentPos);
}
}.start();
while (true)
currentPos = new Point(currentPos.x+1, currentPos.y+1);
}
}
आउटपुट के कुछ नमूने मुझे मिल रहे हैं:
$ java A
145281 145282
$ java A
141373 141374
$ java A
49251 49252
$ java A
47007 47008
$ java A
47427 47428
$ java A
154800 154801
$ java A
34822 34823
$ java A
127271 127272
$ java A
63650 63651
चूँकि यहाँ कोई फ्लोटिंग पॉइंट अंकगणित नहीं है, और हम सभी जानते हैं कि पूर्णांक पर हस्ताक्षर किए गए पूर्णांक जावा में अतिप्रवाह पर अच्छा व्यवहार करते हैं, मुझे लगता है कि इस कोड में कुछ भी गलत नहीं है। हालाँकि, आउटपुट के संकेत के बावजूद कि कार्यक्रम निकास स्थिति तक नहीं पहुंचा था, यह बाहर निकलने की स्थिति तक पहुँच गया (यह दोनों तक पहुँचा गया और पहुँचा नहीं गया?)। क्यों?
मैंने देखा है कि यह कुछ वातावरणों में नहीं होता है। मैं 64 बिट लिनक्स पर OpenJDK 6 पर हूं ।
final
खेतों में क्वालीफायर (जो उत्पादित बायोटेक पर कोई प्रभाव नहीं है) को जोड़ना x
और y
बग को "हल" करता है। हालाँकि यह बाइटकोड को प्रभावित नहीं करता है, लेकिन इसके साथ खेतों को चिह्नित किया जाता है, जो मुझे लगता है कि यह एक जेवीएम अनुकूलन का एक साइड-इफेक्ट है।
Point
p
का निर्माण किया जाता है जो संतुष्ट करता है p.x+1 == p.y
, फिर एक संदर्भ मतदान धागे को दिया जाता है। आखिरकार मतदान सूत्र बाहर निकलने का फैसला करता है क्योंकि यह सोचता है कि Point
यह प्राप्त स्थिति में से किसी एक के लिए स्थिति संतुष्ट नहीं है , लेकिन फिर कंसोल आउटपुट दिखाता है कि इसे संतुष्ट होना चाहिए था। volatile
यहाँ की कमी का अर्थ है कि मतदान धागा फंस सकता है, लेकिन यह स्पष्ट रूप से यहाँ समस्या नहीं है।
synchronized
से बग नहीं होता है? ऐसा इसलिए है क्योंकि मुझे बेतरतीब ढंग से कोड लिखना था जब तक कि मुझे एक ऐसा नहीं मिला जो इस व्यवहार को सामान्य रूप से पुन: पेश करेगा।