मैं जो प्रश्न पूछ रहा हूं वह Difference between StringBuilder and StringBuffer से संबंधित है लेकिन समान नहीं है। मैं देखना चाहता हूं कि वास्तव में क्या होता है यदि एक स्ट्रिंगबिल्डर एक ही समय में दो धागे द्वारा संशोधित किया जाता है।स्ट्रिंगबिल्डर कई धागे द्वारा संशोधित
मैं निम्नलिखित वर्गों ने लिखा है:
public class ThreadTester
{
public static void main(String[] args) throws InterruptedException
{
Runnable threadJob = new MyRunnable();
Thread myThread = new Thread(threadJob);
myThread.start();
for (int i = 0; i < 100; i++)
{
Thread.sleep(10);
StringContainer.addToSb("a");
}
System.out.println("1: " + StringContainer.getSb());
System.out.println("1 length: " + StringContainer.getSb().length());
}
}
public class MyRunnable implements Runnable
{
@Override
public void run()
{
for (int i = 0; i < 100; i++)
{
try
{
Thread.sleep(10);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
StringContainer.addToSb("b");
}
System.out.println("2: " + StringContainer.getSb());
System.out.println("2 length: " + StringContainer.getSb().length());
}
}
public class StringContainer
{
private static final StringBuffer sb = new StringBuffer();
public static StringBuffer getSb()
{
return sb;
}
public static void addToSb(String s)
{
sb.append(s);
}
}
शुरू में मैं StringContainer में एक StringBuffer रखा। चूंकि StringBuffer एक समय में धागे की सुरक्षित, है, केवल एक धागा इसे करने के लिए जोड़ सकते हैं, ताकि उत्पादन अनुरूप है - या तो दोनों धागे की तरह, 200 के रूप में बफर की लंबाई सूचना:
1: abababababababababbaabababababababbaababababababababababababbabaabbababaabbaababababbababaabbababaabababbaabababbababababaababababababababbababaabbaababbaababababababbaababbababaababbabaabbababababaab
1 length: 200
2: abababababababababbaabababababababbaababababababababababababbabaabbababaabbaababababbababaabbababaabababbaabababbababababaababababababababbababaabbaababbaababababababbaababbababaababbabaabbababababaab
2 length: 200
या उनमें से एक 199 और अन्य 200, की तरह सूचना:
2: abbabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
2 length: 199
1: abbababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababa
1 length: 200
महत्वपूर्ण यह है कि पिछले धागा रिपोर्ट 200
की लंबाई अब पूरा करने के लिए है, मैं StringContainer StringBuffer के बजाय यानी
एक StringBuilder करने के लिए परिवर्तितpublic class StringContainer
{
private static final StringBuilder sb = new StringBuilder();
public static StringBuilder getSb()
{
return sb;
}
public static void addToSb(String s)
{
sb.append(s);
}
}
मुझे उम्मीद है कि कुछ लिखने को अधिक लिखित होने की उम्मीद है, जो हो रहा है। लेकिन StringBuilder और लंबाई की सामग्री को कभी कभी मेल नहीं खाते:
1: ababbabababaababbaabbabababababaab
1 length: 137
2: ababbabababaababbaabbabababababaab
2 length: 137
आप देख सकते हैं मुद्रित सामग्री केवल 34 वर्ण है, लेकिन लंबाई 137 है क्यों हो रहा है के रूप में? -
@Extreme Coders मैं बस एक और परीक्षण चालन किया:
2: ababbabababaabbababaabbababaababaabbaababbaaababbaabbabbabbabababbabababbbabbbbbabababbaabababbabaabaaabaababbaabaababababbaabbbabbbbbababababbababaab
1: ababbabababaabbababaabbababaababaabbaababbaaababbaabbabbabbabababbabababbbabbbbbabababbaabababbabaabaaabaababbaabaababababbaabbbabbbbbababababbababaab
1 length: 150
2 length: 150
जावा संस्करण: 1.6.0_45 और मैं ग्रहण संस्करण का उपयोग कर रहा: वेब डेवलपर्स के लिए ग्रहण जावा ईई आईडीई। संस्करण: जूनो सेवा रिलीज़ 2 बिल्ड आईडी: 20130225-0426
अद्यतन 1: मैं इस बाहर ग्रहण भाग गया और अब वे मिलान हो रहे हैं, लेकिन मैं कभी कभी ArrayIndexOutOfBoundsException हो रही है:
$ java -version
java version "1.6.0_27"
OpenJDK Runtime Environment (IcedTea6 1.12.5) (6b27-1.12.5-0ubuntu0.12.04.1)
OpenJDK Server VM (build 20.0-b12, mixed mode)
$ java ThreadTester
1: ababbbbbabbabababababaababbaabbbaabababbbababbabababbabbababbbbbbabaabaababbbbbbabbbbbaabbaaabbbbaabbbababababbbbabbababab
1 length: 123
2: ababbbbbabbabababababaababbaabbbaabababbbababbabababbabbababbbbbbabaabaababbbbbbabbbbbaabbaaabbbbaabbbababababbbbabbababab
2 length: 123
$ java ThreadTester
2: abbabaabbbbbbbbbababbbbbabbbabbbabaaabbbbbbbabababbbbbbbbbabbbbbbbababababbabbbbaabbbaaabbabaaababaaaabaabbaabbbb
2 length: 115
1: abbabaabbbbbbbbbababbbbbabbbabbbabaaabbbbbbbabababbbbbbbbbabbbbbbbababababbabbbbaabbbaaabbabaaababaaaabaabbaabbbb
1 length: 115
$ java ThreadTester
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at java.lang.String.getChars(String.java:862)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:408)
at java.lang.StringBuilder.append(StringBuilder.java:136)
at StringContainer.addToSb(StringContainer.java:14)
at ThreadTester.main(ThreadTester.java:14)
2: abbbbbbababbbbabbbbababbbbaabbabbbaaabbbababbbbabaabaabaabaaabababaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
2 length: 114
ग्रहण से चलते समय ArrayIndexOutOfBoundsException भी हो रहा है।
अद्यतन 2: दो समस्याएं हो रही हैं। स्ट्रिंगबिल्डर की सामग्री की पहली समस्या लंबाई से मेल नहीं खाती है केवल ग्रहण में हो रही है और जब मैं कमांड लाइन में नहीं चलाता (कम से कम 100+ बार मैंने इसे कमांड लाइन पर चलाया तो यह कभी नहीं हुआ)।
ArrayIndexOutOfBoundsException के साथ दूसरी समस्या स्ट्रिंगबिल्डर वर्ग के आंतरिक कार्यान्वयन के साथ करना चाहिए, जो वर्णों की एक सरणी रखता है और आकार को विस्तारित करते समय Arrays.copyOf
करता है। लेकिन यह अभी भी मुझे धड़कता है कि आकार का विस्तार होने से पहले एक लेखन कैसे हो रहा है, इससे कोई फर्क नहीं पड़ता कि निष्पादन का आदेश क्या है।
बीटीडब्ल्यू, मैं @ ग्रेबेर्डेडजीक के उत्तर से सहमत हूं कि यह पूरा अभ्यास समय की एक बड़ी बर्बादी है :-)। कभी-कभी हमें केवल कुछ लक्षणों को देखने के लिए लक्षण मिलते हैं और आश्चर्य होता है कि क्या गलत हो रहा है।यह सवाल घोषित एक प्रायोरी कि दो धागे एक (बहुत अच्छी तरह से जाना जाता है) धागा असुरक्षित वस्तु संशोधित कर रहे हैं।
अद्यतन 3: यहां Java Concurrency in Practice पी का आधिकारिक उत्तर दिया गया है। 35:
तुल्यकालन, संकलक, प्रोसेसर और क्रम के अभाव जिस क्रम में आपरेशन निष्पादित करने के लिए प्रकट करने के लिए कुछ पूरी तरह अजीब बातें करते हैं सकते हैं। प्रयास में जिस क्रम स्मृति कार्यों अपर्याप्त सिंक्रनाइज़ बहु कार्यक्रमों में भी हो "चाहिए" लगभग निश्चित रूप से गलत होगा के बारे में तर्क करने की।
अपर्याप्त रूप से सिंक्रनाइज़ समवर्ती कार्यक्रमों के बारे में तर्क निषिद्ध रूप से कठिन है।
पी पर पुस्तक में NoVisibility
का एक अच्छा उदाहरण भी है। 34.
कि अजीब बात है, मेरे मशीन पर इसे बाहर प्रिंट '199' और' 200' और 'StringBuilder' के आकार वर्ण की संख्या के रूप में ही है। मैंने यह कई बार भाग लिया है लेकिन प्रत्येक बार एक ही परिणाम प्राप्त करने के लिए –
यह भी आईडीई के साथ कुछ करने के लिए है। प्रारंभ में मैंने इंटेलिजे का इस्तेमाल किया और यह हमेशा '199' और' 200' की लंबाई देता था। इसके बाद मैंने इसे ब्लूजे में चलाया और यह हर रन पर परिवर्तनीय लंबाई प्रदान करता है। ऐसा लगता है कि इंटेलिजे अन्य आईडीई की तुलना में एकाधिक धागे को संभालने में बेहतर है। –
कमांड लाइन आईडीई से परिणाम प्राप्त करने का कोई मौका? :) –