使用Stringbuffer作为servlet中的实例变量时的竞争条件

时间:2015-04-02 09:24:58

标签: java servlets thread-safety race-condition stringbuffer

我的代码就是那样

public class MyServlet extends Action
{
    Stringbuffer s=null;

    public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse res)
    {

        s = "hello";//or some dynamic value 

    }
}

我的问题是这个实例变量是否为'是不是线程安全。

任何帮助都将不胜感激。

提前致谢

4 个答案:

答案 0 :(得分:0)

您正在创建Stringbuffer的新实例,因此它不是线程安全的。虽然如果您尝试在StringBufer上执行任何进一步操作,StringBuffer本身就是线程安全的。

答案 1 :(得分:0)

因为我认为 servlets 中的实例变量而不是threadsafe ,因为只有一个servlet类实例被所有请求线程创建和共享。 struts 遵循 servlet 模型。

一个类被描述为"线程安全"并不意味着它始终是线程安全的。如果单个方法同步,这可能还不够 - 您可能最好在更高级别进行同步。

因为在相同的StringBuffer对象上,多个线程可以更改对象的状态。假设一个线程正在调用一个方法append并附加一些String。在此其他线程之后替换同一对象中的某个字符。在此事件中,第一个线程将不会知道对象中所做的更改。 因此在使用线程安全类型时我们需要额外的线程安全性。

答案 2 :(得分:0)

StringBuffer是ThreadSafe,因为它的实现是同步的。但是你的实现不是线程安全的。

如果您使用StringBuffer实例,它将是Thread安全的:您的实现中存在两个主要问题:

  • 您将值设置为“null”=>它只需要实例化一次即可实现实例的同步。

  • 您在execute =>中设置了值这不是线程安全的,因为影响不同步:只使用StringBuffer的方法来设置值。

所以正确的代码应该是:

 public class MyServlet extends Action
 {
 Stringbuffer s=new StringBuffer();

   public ActionForward execute(ActionMapping mapping, ActionForm form,     HttpServletRequest req, HttpServletResponse res)
   {
      s.setLength(0);// if you want to replace value
      s.append("hello");//or some dynamic value 

   }
}

编辑:重新制定

答案 3 :(得分:0)

在这种情况下,s是对象的引用,无论它指向哪个类,都不是线程安全的。但是,这个MyServlet对象不应该被多个线程访问,所以它不是线程安全的事实是非常合理的。

BTW请不要使用StringBuffer,因为十年前它被StringBuilder取代了。