【问题标题】:StringBuilder vs StringBufferStringBuilder 与 StringBuffer
【发布时间】:2017-05-27 06:48:27
【问题描述】:

StringBuffer 和 StringBuilder 之间唯一/主要的区别是 StringBuffer 是线程安全的,而 StringBuilder 不是。

所以当要从单线程访问时使用StringBuilder,当要从多线程访问时使用StringBuffer。

让我们考虑一个 servlet 的例子:

public class MyClass extends HttpServlet {
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      StringBuilder sb1 = new StringBuilder();
  }
}

现在当请求到达 servlet 容器时,新线程将被创建,因此上面示例中的 get 方法将被多个线程访问。

问题是:

  1. StringBuilder 的非同步性质是否是这里的一个问题,相同的 StringBuilder 是跨线程共享还是在方法中声明,因此每个线程都有单独的 StringBuilder?
  2. 在哪种情况下,StringBuffer 必须优先于 StringBuilder?

【问题讨论】:

    标签: java multithreading servlets


    【解决方案1】:

    sb1 是一个局部变量,所以每个线程都有自己的实例(每个线程都会执行new StringBuilder() 语句)。在这种情况下使用 StringBuilder 是完全安全的。

    如果你的代码是这样的,那将是一个问题:

    public class MyClass extends HttpServlet {
    
       private StringBuilder sb1 = new StringBuilder();
    
      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
      }
    }
    

    在这种情况下,您会遇到问题,因为所有线程都使用同一个 MyClass 实例,因为容器只为每个 servlet 创建一个由所有线程共享的实例。

    还请注意,在这种情况下,即使是 StringBuffer 也会有问题,因为对该属性的操作将是“原子的”(同步的),但您无法确保访问该资源的顺序,结果可能会很混乱。

    【讨论】:

      【解决方案2】:

      1) 在 servlet 上下文中,每个 servlet 实例在多个请求之间共享。因此,如果您为 servlet 创建实例变量,您可能会遇到线程安全问题,因为每个请求也共享相同的内存以及实例变量。在您的情况下,StringBulder 实例是在 doGet 方法内创建的,因此您不会遇到该问题。另一种方法是使用线程同步

      2)也许使用StringBuffer会更好,因为你不必每次都重新声明局部变量

      【讨论】:

        猜你喜欢
        • 2011-06-06
        • 2011-02-27
        • 2014-07-22
        • 2015-12-13
        • 2011-04-16
        • 2010-09-26
        • 2023-03-04
        • 2011-04-16
        相关资源
        最近更新 更多