以下程序在使用StringBuilder时有时会抛出异常,但在使用StringBuffer时绝不会抛出异常。
程序:
public class StringBuilderConcurrent {
static final StringBuilder sb = new StringBuilder(); // shared memory
public static void main(String[] args) throws Exception {
int NUM_WRITERS = 300;
ArrayList<WriterThread> threads = new ArrayList<WriterThread>(NUM_WRITERS);
for (int i = 0; i < NUM_WRITERS; i++) {
WriterThread wt = new WriterThread("writerThread" + i);
threads.add(wt);
wt.start();
}
for (int i = 0; i < threads.size(); i++) {
threads.get(i).join();
}
System.out.println(sb);
}
public static class WriterThread extends Thread {
public WriterThread(String name) {
super(name);
}
public void run() {
String nameNl = this.getName() + "\n";
for (int i = 1; i < 20; i++) {
sb.append(nameNl);
}
}
};
}
因为 StringBuilder ( sb
) 不是线程安全的,让多个线程写入数据sb
可能会导致sb
损坏(例如,意外的空字符,一个单词的字母与其他单词的字母穿插在一起)。的内部状态也可能sb
变得不一致,以至于可能引发异常:
Exception in thread "writerThread0" java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at java.lang.String.getChars(String.java:854)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:391)
at java.lang.StringBuilder.append(StringBuilder.java:119)
at test.StringBuilderConcurrent$WriterThread.run(StringBuilderConcurrent.java:35)
以下程序与第一个程序相同,只是它使用 StringBuffer 而不是 StringBuilder。它永远不会遇到 ArrayIndexOutOfBoundsException。
public class StringBufferConcurrent {
static final StringBuffer sb = new StringBuffer(); // shared memory
public static void main(String[] args) throws Exception {
int NUM_WRITERS = 300;
ArrayList<WriterThread> threads = new ArrayList<WriterThread>(NUM_WRITERS);
for (int i = 0; i < NUM_WRITERS; i++) {
WriterThread wt = new WriterThread("writerThread" + i);
threads.add(wt);
wt.start();
}
for (int i = 0; i < threads.size(); i++) {
threads.get(i).join();
}
System.out.println(sb);
}
public static class WriterThread extends Thread {
public WriterThread(String name) {
super(name);
}
public void run() {
String nameNl = this.getName() + "\n";
for (int i = 1; i < 20; i++) {
sb.append(nameNl);
}
}
};
}
这些程序是否代表“现实世界”问题是一个相当主观的问题。我会把这个判断留给观众。