【问题标题】:Java: Rule Of Thumb For Using Synchrozined Collections?Java:使用同步集合的经验法则?
【发布时间】:2012-08-06 22:09:14
【问题描述】:

我正在阅读 Stackoverflow thread 关于使用 StringBuilder 与 StringBuffer 的内容。

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

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

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

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

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

【问题讨论】:

  • 您可能打算用 StringBuilder 替换 StringBuffer。换句话说,删除不必要的同步。

标签: java collections synchronize


【解决方案1】:

我们使用StringBuilder 而不是StringBuffer,因为我们认为多个线程不会给我们带来问题。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 好点。我认为我所有的 StringBuffers 都存在于函数中,所以它们都是局部变量。
    【解决方案3】:

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

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

    【讨论】:

    • 我是否可以在不知道自己正在这样做的情况下开始一个新线程(即编写 new Thread() )?如果我不这样做,我对非同步集合是否安全?
    • 除非您创建new Thread 或使用ExecutorService 并且您自己编写所有代码,否则您不需要同步任何东西。唯一的例外是您正在创建一个 Swing 应用程序。除了这个例外,这种情况很少见。
    • 这真的取决于。如果您使用的是第三方库,您将一些侦听器和/或回调传递给它可以很好地在不同的线程上调用它们。
    • 但它又带来了我原来的论点。如果您不确定何时使用它,可以肯定地假设您不会最有效地使用它(我从经验中这么说,因为我过去遇到过同样的问题)。最好的办法是阅读各种书籍,如 JCiP 甚至 Java 中的并发编程(以获得基础)。
    【解决方案4】:

    这个链接说得最好:

    * 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”)。

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

    恕我直言...

    【讨论】:

    • 我认为这个问题需要澄清“尽可能使用新的 StringBuilder。”,即你如何确保它是可能的。
    • 没错,我将您的短语放入我的问题中。清楚明了,谢谢。
    • 上面暗示的两个经验法则:1)如果没有线程:别担心。使用 StringBuilder ;) 2) 如果你有线程......但是正在进行的字符串是一个局部变量:别担心 ;)。另外:如果您认为自己可以更好地锁定 - 去吧。使用字符串生成器。够清楚;)?
    【解决方案5】:

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

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

    【讨论】:

      【解决方案6】:

      在您确定需要同步之前使用未同步的东西。

      部分问题与例如StringBufferVector 是它们并不总是以正确的方式同步。对于Vector,您并不总是需要 单独同步每个操作;通常,您真正想要的是同步操作块...Vector 不一定比 ArrayListCollections.synchronizedList 更好。

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

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

      【讨论】:

      • +1 “即使你决定以后使用并发,那也不一定是正确的并发。”
      • +1 SimpleDateFormat 使用 StringBuffer 但不是线程安全的,因为它没有正确实现。
      【解决方案7】:

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

      不,不是。

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

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

      但是从某种意义上说,您是正确的,当不可能有多个线程使用数据结构时使用同步数据结构是(有点)浪费。但是再也没有像过去互斥锁很昂贵那样浪费了。


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

      通过理解您的代码。 StringBuilder 可以被其他线程看到吗?如果没有,那么使用它是安全的。否则,共享StringBuilder 的线程需要同步。做到这一点的一种方法可能是使用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();
        }
      

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

      【讨论】:

      • 我知道 JSP 只是 Servlet,但是在 JSP 中使用非同步集合是否安全? Servlet 使用的类呢?像 Spring 这样的框架中的编码函数呢?
      • @Steve - 答案是“视情况而定”。如果涉及的对象是线程限制的,那么它是安全的。否则,概括起来太复杂了。
      • 我如何知道我的代码是否可以被其他线程看到?我不是故意创建任何线程。除了 Servlet 和 Swing 之外,是否还有其他情况可以为我完成并可能导致问题?
      • 线程受限的是对象,而不是代码。答案是“通过阅读和理解你的代码”。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-14
      • 1970-01-01
      • 2014-08-10
      相关资源
      最近更新 更多