public class Test {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("AAAAABBBBB");
StringBuffer bf=new StringBuffer("AAAAABBBBB");
for(int i=0;i<10;i++) {
new Thread(new TR(builder)).start();
}
}
}
class TR implements Runnable{
private StringBuilder sb;
//private StringBuffer sb;
TR(StringBuilder builder){
sb=builder;
}
@Override
public void run() {
int k;
for(k=0;k<1000;k++) {
sb.reverse();
}
System.out.println(sb);
}
}
StringBuilder的reverse原理是把第j个和第n-j个交换,具体细节见下面代码,当两个及以上的线程同时对同一个StringBuilder对象操作时,可能会出现第一个Reverse正在交换第二个A和第8个B,此时另一个线程进来在中间过程的基础上进行Reverse
从而导致最后结果不在AAAAABBBBB和BBBBBAAAAA这两种情况中。若把相关参数改为StringBuffer
则不会出现这种情况。
public AbstractStringBuilder reverse() {
boolean hasSurrogate = false;
int n = count - 1;
for (int j = (n-1) >> 1; j >= 0; --j) {
char temp = value[j];
char temp2 = value[n - j];
if (!hasSurrogate) {
hasSurrogate = (temp >= Character.MIN_SURROGATE && temp <= Character.MAX_SURROGATE)
|| (temp2 >= Character.MIN_SURROGATE && temp2 <= Character.MAX_SURROGATE);
}
value[j] = temp2;
value[n - j] = temp;
}
if (hasSurrogate) {
// Reverse back all valid surrogate pairs
for (int i = 0; i < count - 1; i++) {
char c2 = value[i];
if (Character.isLowSurrogate(c2)) {
char c1 = value[i + 1];
if (Character.isHighSurrogate(c1)) {
value[i++] = c1;
value[i] = c2;
}
}
}
}
return this;
}
试验结果如下:
另一种StringBuffer: