StringBuilder与StringBuffer

时间:2017-01-12 08:40:15

标签: java multithreading servlets

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

因此,当要从单个线程访问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?

2 个答案:

答案 0 :(得分:3)

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也会有问题,因为对该属性的操作将是" atomic" (已同步)但您无法确保访问该资源的顺序,结果可能会很混乱。

答案 1 :(得分:0)

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

2)也许使用StringBuffer会更好,因为您每次都不得重新声明本地变量