StringBuffer同步如何工作?

时间:2015-02-11 17:04:30

标签: java multithreading synchronization stringbuffer

向大家致以问候!

我对以何种方式/在什么情况下StringBuffer被同步并且阻止多线程访问感到困惑。在下面的代码中,它打印出for循环中的字母A 100次然后B 100次等...注释出synchronized(sb){}部分,它不再同步且不起作用......

如何将StringBuffer同步......在什么限制条件下它会起作用?有人可以简单解释一下吗?它必须是原子操作吗?

谢谢!

约翰。

package threads.sync.ch13;

import java.util.ArrayList;
import java.util.List;

class Ex13_2 extends Thread {

static StringBuffer sb;
// StringBuilder sb;
String s;

public Ex13_2(StringBuffer sb) {

    this.sb = sb;

}

public void run() {
    synchronized (sb) {
        // incr letter then print 100 X
        sb.replace(0, sb.length(), this.s);
        for (int i = 0; i < 100; i++) {
            System.out.print(this.sb);
        }
        System.out.println();

    }

}

public static void main(String[] args) {

    // single Class Buffer per Instance...
    sb = new StringBuffer("");

    // Create Array of Multiple Thread Instances
    // and start running them...
    List<Ex13_2> e = new ArrayList<>();

    for (char c = 'A'; c <= 'D'; c++) {
        Ex13_2 t = new Ex13_2(sb);
        t.s = c + "";
        e.add(t);

    }

    for (Ex13_2 t : e) {
        t.start();
    }

}

}

2 个答案:

答案 0 :(得分:2)

首先,对于非共享使用,StringBuilder是优越的(它是为此目的编写的......它完全不同步,所以更快一点)。

返回StringBuffer。它的所有公共方法都是同步的,所以它在内部是“安全的”。但以下不是原子的:

StringBuffer sb = //get_sb_from_somewhere;
sb.append("foo").append("bar);

要使附加完全线程安全,请使用对象将使用的相同锁将它们包装在锁中。通常这只是对象,就像这里的情况一样,所以:

synchronized (sb) {
  sb.append("foo").append("bar);
}

你的run()方法看起来不错。

答案 1 :(得分:0)

StringBuilder 中的每个方法都是线程安全的。但是你按顺序调用各种方法。因此,对方法的每次调用都是互斥的,而不是整个系列的调用。

通过将整个系列放入synchronized(sb) {}块,可以使整个系列的调用互斥。