【问题标题】:Multithreading - StringBuffer and StringBuilder多线程 - StringBuffer 和 StringBuilder
【发布时间】:2011-04-16 16:58:45
【问题描述】:

如果您的文本可以更改并且只会更改 从单个线程访问,使用 一个 StringBuilder 因为 StringBuilder 是不同步的。

如果您的文字可以更改,并且将 从多个线程访问,使用 StringBuffer 因为 StringBuffer 是 同步。

多线程是什么意思?谁能解释一下这个?我的意思是两个方法或两个程序试图同时访问另一个方法。

【问题讨论】:

  • 表示当2个或更多线程同时访问同一个对象时。例如,1 个线程可能会尝试获取字符串的值,而另一个线程可能会对其进行更新。这是已知的“同步”问题。 stringBuffer 可以是 2 个或更多线程访问的任何对象。

标签: java


【解决方案1】:

线程是可以同时执行的执行路径。你的Java程序中可以有多个线程,它们可以同时调用同一个对象的同一个方法。如果方法例如在屏幕上打印一些东西,您可能会看到来自不同线程的消息混乱 - 除非您明确确保一次只能打印一条消息,并且所有其他打印请求应等到实际消息完全打印。 /p>

或者,如果您在该对象中有一个字段,所有线程都会看到它。如果其中一个修改了该字段......那是有趣的部分开始的时候:-) 其他线程可能只会在以后看到更新的值,或者根本看不到,除非您特别确保它可以安全地被多个线程使用线程。这可能会导致细微的、难以重现的错误。这就是为什么正确编写并发程序是一项艰巨的任务。

在单处理器内核的机器上,任何时候只能运行一个线程,因此不同的线程会一个接一个地执行,但是操作系统会频繁地在它们之间切换(每秒很多次) ,从而给用户一种看到多个线程并行运行的错觉。 OTOH 多核机器实际上可以同时运行多个线程 - 与它们拥有的处理器内核一样多。

每个 Java 程序至少有一个线程。您可以在程序中手动创建额外的线程并将任务传递给它们以执行。

可以在Java Tutorials 中找到线程和进程的详细说明,以及 Java 中的并发性。

【讨论】:

  • @John,这个问题的答案已经有了——我现在用粗体强调了它:-)
  • @John:每个独立的执行路径都是一个线程。因此,根据定义,执行一个只包含 main 方法的 Java 程序也是一个线程。
【解决方案2】:

Threads 喜欢小进程。

考虑一个字符串在同时运行的两个线程之间共享的情况。

他们都在上面操作。因此,这将是两个线程都在操作字符串的情况,因此它不会保持一致状态。

所以。

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

  • 在大多数情况下,StringBuilder 的性能优于 StringBuffer。

  • 尽可能使用新的 StringBuilder。

有关并发的更多信息,请参阅this

【讨论】:

  • 字符串是不可变的,它不能被“操纵”。字符串本身是线程安全的。
  • 每个 java 程序至少有一个由主类启动的main 线程。但可能还有很多其他
  • 在简单的java应用程序中默认有一个主线程,您可以使用线程类启动多个线程,有关线程的更多信息请参考:download.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html
  • 您可以从主线程开始新线程。并从他们那里再次获得新的。
【解决方案3】:

我认为您可以在这两种情况下使用StringBuilder,但在多线程程序中要非常注意。 StringBuffer 方法级别的同步在您必须对此类字符串执行更多操作(就像在数据库事务中一样)时没有用,例如在开头删除 3 个字符,然后在末尾删除 3 个字符,并将其与某些内容进行比较。即使这样的删除操作是同步的(因此是原子的),您也可以:

  1. 第一个线程可以得到这样的字符串,并删除开头的3个字符
  2. 第二个线程获取这样的字符串并在开头删除3个字符
  3. 字符串状态不一致(从开头删除了 6 个字符)

您应该在方法级别同步对此类变量的访问,而不是依赖于StringBuffer 方法同步。使用StringBuffer,您将拥有两个级别的同步,而使用StringBuilder,您将只有自己的同步。

【讨论】:

    【解决方案4】:

    多线程;多线程就像在同一时间运行同一程序的各个部分,共享相同的数据。

    一个典型的例子是当程序需要进行长时间的计算时,它可以创建一个单独的线程在后台进行计算,并在主线程上不断响应用户输入。

    多个线程的问题在于,由于它们同时运行,而您现在并不真正了解它们在做什么,因为它们可以做出自己的决定,因此将某些操作依赖于共享数据变得很危险总是按一定的顺序完成。

    使用 thqt 进行 deqling 的技术有很多种,其中一种是 qllow 同步访问的同步键。这意味着一个线程在忙时会阻塞对 Object 的访问,因此当其他线程想要访问时,它们必须等待。

    这就是 StringBuffer 是同步的意思,当一个线程更新它时,它将阻止对她的线程的访问。

    使用多线程被认为是一个高级主题,并非所有问题都以令人满意的方式解决。依靠“同步”对象来处理并发不会让您走得太远,因为通常您将以协调的方式对多个对象进行更新,并且这些对象也必须同步。

    我的建议:在您读完一本好书并进行练习之前,请远离那里。直到那时,线程之间不共享任何数据(除了最简单的信号标志)。

    【讨论】:

      猜你喜欢
      • 2011-02-27
      • 1970-01-01
      • 2017-05-27
      • 2010-09-26
      • 2017-08-23
      • 2015-12-13
      相关资源
      最近更新 更多