2

我正在阅读有关使用 StringBuilder 与 StringBuffer 的Stackoverflow线程。

底线似乎是这两个集合是相同的东西,除了 StringBuffer 是同步的,是线程安全的,并且与不是那些东西的 StringBuilder 相比,性能稍差。

有人提出 ArrayList 和 Vector 之间存在类似的关系。

除非我有意识地创建多个线程,否则不使用同步集合(或其他任何东西)是一个好的(安全)经验法则吗?

换句话说,我收到消息“尽可能使用新的 StringBuilder。”,我想知道的是,我如何确定它是可能的?

只要我不故意创建新线程,我使用非同步集合是否安全?

4

7 回答 7

5

使用不同步的东西,直到你确定你需要同步。

eg StringBufferandVector的部分问题在于它们并不总是以正确的方式同步。因为Vector,您并不总是需要单独同步每个操作;通常,您真正想要的是同步操作块……这不一定Vector比.ArrayListCollections.synchronizedList

当你知道你正在使用并发和多线程时,然后计算出你需要什么同步的细节,但只是换成StringBuffer只会StringBuilder给你一种错误的安全感——即使你决定以后使用并发,那不是一定是正确并发。

(如果您当前没有使用线程,那么绝对可以 - 甚至推荐 - 查找并替换StringBufferStringBuilder。上述参数是相反的方向。)

于 2012-08-09T16:18:11.777 回答
1

在您知道如何自己回答这个问题之前,我会说总是使用非阻塞的任何东西。同步一切真的很容易,创建和启动线程也很容易。了解何时使用同步以及何时创建线程需要一段时间。

您应该从阅读 Java 并发实践开始。

于 2012-08-09T16:15:56.613 回答
1

看起来你在这里问了多个问题。因此,首先,除非绝对必要,否则避免同步确实是一个好主意。

在第二个问题上,将 StringBuilder 替换为 StringBuffer 也是安全的,反之亦然,除非它们的值可以从多个线程中更改。

于 2012-08-09T16:16:42.543 回答
0

除非我有意识地创建多个线程,否则不使用同步集合(或其他任何东西)是一个好的(安全)经验法则吗?

不它不是。

在某些情况下会涉及多个线程,即使您没有有意识地创建它们。例如,任何使用 Swing 或 Servlets 的应用程序都有可能在不同线程上的应用程序代码之间进行交互。(你甚至可以争辩说,如果你使用标准的线程池实现,你并没有显式地创建线程。)

此外,使用同步集合并不一定能保证线程安全。

但是从某种意义上说,您是正确的,当不可能有多个线程使用数据结构时使用同步数据结构是(有点)浪费。但是没有什么地方比过去互斥量昂贵的时候更浪费了。


换句话说,我收到消息“尽可能使用新的 StringBuilder。”,我想知道的是,我如何确定它是可能的?

通过理解你的代码。StringBuilder其他线程可以看到吗?如果没有,那么使用它是安全的。否则,共享的线程StringBuilder需要同步。一种方法可能是使用 a StringBuffer,但这不一定会给您正确的同步粒度。

这是一个简单的例子:

  public String nTimes(String str, int n) {
      StringBuilder sb = new StringBuilder();
      for (int i = 1; i <= n; i++) sb.append(str);
      return sb.toString();
  }

在上面,StringBuilderinsb永远不会被另一个线程看到,所以不需要同步它。

于 2012-08-09T16:24:40.097 回答
0

我们正在使用StringBuilder而不是StringBuffer因为我们不认为多个线程会导致我们出现问题。

于 2012-08-09T16:15:24.080 回答
0

如果没有进一步分析,自动在整个代码库上执行此操作听起来有点危险,除非您 100% 肯定这些对象(向量、字符串缓冲区)不是跨线程共享的,或者同步对象的选择不是由线程驱动的首先是安全分析。

可以毫无风险地进行交换的一种简单情况是局部变量,显然不能跨线程共享(除非您返回它们)。

于 2012-08-09T16:15:39.767 回答
0

这个链接说得最好:

* http://javahowto.blogspot.com/2006/08/stringbuilder-vs-stringbuffer.html

StringBuilder 是在 JDK 1.5 中引入的。StringBuilder 和 StringBuffer 有什么区别?根据 javadoc,StringBuilder 被设计为单线程使用中 StringBuffer 的替代品。简单来说,它们的主要区别:

  • StringBuffer 被设计为线程安全的,并且 StringBuffer 中的所有公共方法都是同步的。StringBuilder 不处理线程安全问题,并且它的所有方法都没有同步。

  • 在大多数情况下,StringBuilder 比 StringBuffer 具有更好的性能。

  • 尽可能使用新的 StringBuilder。

根据我自己的经验:

  • 对于任何严重的字符串操作,请始终使用 StringBuilder(从不使用“String”)

  • 我从来没有使用过 StringBuffer(我总是只使用“StringBuilder”)。

  • 只有当从多个线程同时访问相同的正在进行的字符串时,您才应该考虑“StringBuffer”。即使这样,您也可能会发现使用自己的锁定更容易/更有效。

恕我直言...

于 2012-08-09T16:16:39.330 回答