为啥 StringBuilder 访问似乎是同步的? [复制]

Posted

技术标签:

【中文标题】为啥 StringBuilder 访问似乎是同步的? [复制]【英文标题】:Why does StringBuilder access appear to be synchronized? [duplicate]为什么 StringBuilder 访问似乎是同步的? [复制] 【发布时间】:2013-10-16 08:57:33 【问题描述】:

我想知道 StringBuilder 和 StringBuffer 类之间的区别以及它们的实际用途。因此,我编写了 2 个代码 sn-ps,其中我同时生成了 3 个线程,这些线程使用了 StringBuilder 和 StringBuffer 对象。

当我运行代码时,我希望所有 3 个线程在 StringBuilder 的情况下同时运行,在 StringBuffer 的情况下以同步的方式运行。但在这两种情况下,它们都以同步方式运行。 那么StringBuffer类有什么用呢?:confused:

(对于 String 对象,所有 3 个线程同时运行)。我将分享代码 sn-ps 供您参考。如果我对多线程本身的概念理解有误,也请纠正我。请同时更正代码。

// StringBuilder...

public class MultiTread implements Runnable
private StringBuilder name;
public MultiTread(StringBuilder string)
name=string;


public void run()
for(int i=0; i<=10; i++)
System.out.println(name.append(i));


public static void main(String[] args)
Thread th = new Thread(new MultiTread(new StringBuilder("thread1:")));
Thread th1 = new Thread(new MultiTread(new StringBuilder("thread2:")));
Thread th2 = new Thread(new MultiTread(new StringBuilder("thread3:")));

th.start();
th1.start();
th2.start();



..................

//StringBuffer...

public class MultiTreadBuf implements Runnable
private StringBuffer name;
public MultiTreadBuf(StringBuffer string)
name=string;


public void run()
for(int i=0; i<=10; i++)
System.out.println(name.append(i));


public static void main(String[] args)
Thread th = new Thread(new MultiTreadBuf(new StringBuffer("thread1:")));
Thread th1 = new Thread(new MultiTreadBuf(new StringBuffer("thread2:")));
Thread th2 = new Thread(new MultiTreadBuf(new StringBuffer("thread3:")));

th.start();
th1.start();
th2.start();



........

//String....

public class MuiltiTreadStr implements Runnable
private String name;
public MuiltiTreadStr(String string)
name=string;


public void run()
for(int i=0; i<=10; i++)
System.out.println(name+i);


public static void main(String[] args)
System.out.println("main begins...");
Thread th = new Thread(new MuiltiTreadStr("thread1:"));
Thread th1 = new Thread(new MuiltiTreadStr("thread2:"));
Thread th2 = new Thread(new MuiltiTreadStr("thread3:"));
System.out.println("spawning 3 threads...");
th.start();
th1.start();
th2.start();
System.out.println("main ends...");

 

【问题讨论】:

谷歌,第一个结果是:***.com/questions/355089/… 【参考方案1】:

您正在为每个线程使用不同的 StringBuffers 和 StringBuilders 实例。要查看同步,您必须在所有线程中使用相同的对象实例;-)

【讨论】:

事实上,OP 的代码测试的唯一线程行为是System.out.println() - 其他一切都在自己的线程中运行。【参考方案2】:

您应该为所有线程使用相同的 StringBuilder/StingBuffer 实例。以便您可以看到同步。

【讨论】:

【参考方案3】:

对预期行为与实际行为的描述会有所帮助,但我猜您看到了每个线程的顺序输出,但预计会看到不同线程交错的输出。

线程调度取决于系统。不能保证线程将被公平调度(例如,具有相同优先级的线程获得“时间片”),或者线程将并发运行,即使在多处理器系统上也是如此。

另外,请记住System.out.println() 是同步的,并且不能保证公平或立即解决对固有锁的争用。所以有可能一个线程重复获取System.out 上的锁,而其他线程在该线程完成之前没有机会打印。您可以使用java.util.concurrent.ReentrantLock 获得“公平”锁定(可能会降低性能)。

另一种可能是你的系统太快了,以至于一个线程在下一个线程开始运行之前就完成了。更多的迭代将有助于检测这种情况。

【讨论】:

+1。 System.out.println() is synchronized,还没想好。很好的解释

以上是关于为啥 StringBuilder 访问似乎是同步的? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

String StringBuffer StringBuilder

Java StringBuffer 和 StringBuilder 类

C# stringbuilder为啥高效

Java StringBuffer 和 StringBuilder 类

JAVA StringBuffer 和 StringBuilder 类

Java StringBuffer 和 StringBuilder 类