【问题标题】:what is the need to bind StringBuffer to synchronized block?将 StringBuffer 绑定到同步块需要什么?
【发布时间】:2014-05-24 17:00:31
【问题描述】:

我有一个疑问。众所周知,StringBuffer 是线程安全的(它的方法是synchronized),而StringBuilder 不是线程安全的。

如果StringBuffer本身是线程安全的,那为什么我在修改的时候还要把它放在synchronized block里面。下面是代码:

class SyncTest extends Thread 
{   
    StringBuffer sb;

    public SyncTest(StringBuffer sb) 
    {
        this.sb = sb;   
    }

    public void run() 
    {
        synchronized(sb) 
        {
            for(int i = 1;i<=10;++i) 
            {
                System.out.print(sb);
            }
            sb.setCharAt(0, (char) (sb.charAt(0)+1));// incrementing the char by 1, thus modifying the StringBuffer
        }
    }

    public static void main(String [] args) 
    {
        StringBuffer sb = new StringBuffer("A");

        new SyncTest(sb).start();
        new SyncTest(sb).start();
        new SyncTest(sb).start();    
    }
}

输出:

AAAAAAAAAA
BBBBBBBBBB
CCCCCCCCCC

当我删除 synchronized block 时,输出会发生如下变化:

AAAAAAAAAAAAAAAAA
ABBBBBBBB
ACCC

那么,当我们说StringBuffer 是线程安全的时,这意味着什么。谁能解开我对此的疑惑?

【问题讨论】:

  • StringBuffer单个操作是线程安全的;两个操作,一个接一个,不是。请注意,Hashtable 也是如此。

标签: java multithreading synchronized stringbuffer


【解决方案1】:

您正在执行复合操作。您既要显示它又要修改它。这两个操作本身都是线程安全的,但是当这样组合时,它们就不是了。

一个线程可以修改内容,而另一个线程正在显示单个字符。

【讨论】:

    【解决方案2】:

    StringBuffer被同步意味着每个方法调用都是同步的,但连续两次调用不同步。

    如果你这样做

    sb.append("Hello Dolly");
    

    您可以保证没有其他操作会在两个单词中间附加任何内容。

    如果你这样做

    sb.append("Hello ");
    sb.append("Dolly");
    

    sb 可以以包含 Hello whateverDolly 结尾。

    避免前者的唯一方法是在需要的上下文中执行同步。

    【讨论】:

      猜你喜欢
      • 2017-09-29
      • 2019-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-12
      • 1970-01-01
      • 2016-09-01
      相关资源
      最近更新 更多