我真的应该关心servlet Action类中的线程安全问题吗?

时间:2011-11-18 03:27:36

标签: java multithreading servlets thread-safety

servlet类处理传入的请求对象,获取数据和数据。存储到StringBuilder / StringBuffer中,并将数据传递给另一个类以写入文件。

ActionClass
    public void doPost(HttpServletRequest request,HttpServletResponse response)
   throws ServletException,IOException {
        String fileName = request.getparameter("fileName");
        String body = request.getParameter("innerHTML");
        String head = request.getParameter("headContents");

        StringBuilder sbr = new StringBuilder();
        sbr.append(body);  sbr.append(head);
                        OR
        StringBuffer sbf = new StringBuffer();
         sbf.append(body);  sbf.append(head);

   FileWrite fw = new FileWrite(fileName, sbf/sbr); /* write the data into file*/
          }

FILEWRITE

    class FileWrite{
       public FileWrite(String fileName, StringBuilder sbf){
        boolean isExist = checkFileName(fileName);  /* return true or false */
         if(isExist){
           String name =  reName(fileName);  /* rename & return new name */
                 /* write the file in new file */
          }else{  /* write in same file name */  }
      }

   public String reName(String oldName){
             /* rename oldName as newName & checks via isExist(newName) */
            } 

   public boolean isExist(String filename) {
         // checks the file in directory, if found already
       return true;
           else return false;
         }
    }

正如您在上面的示例中所看到的,action类将数据传递给FileWrite class,后者将数据写入新文件。有数百个客户端可能同时发送请求将数据存储在新文件中 所以我的问题是,在servlet类中 我应该用什么来存储数据。 String or stringBuffer or StringBuilder ??这是线程安全的问题吗?

6 个答案:

答案 0 :(得分:3)

是的,您应该关心线程安全问题,但线程安全问题不在您选择的String或stringBuffer或StringBuilder中。

如果你需要为FileWriter类获得两个相同文件名的请求,那么你需要注意(可能)线程安全。

另外,我要注意,从安全角度来看,直接从get参数中直接获取原始文件位置是非常危险的 - 因为用户可以覆盖其他用户文件,或者(甚至可能取决于权限)甚至OS文件。 / p>

答案 1 :(得分:2)

只要它发生在servlet的doGet或doPost中,那么你只处理一个线程。因此,不需要线程安全,这意味着你应该使用比StringBuffer更快的StringBuilder。

答案 2 :(得分:1)

对于每个新请求,都会生成一个新的servlet线程,该线程具有自己正确包装的唯一上下文。因此,doPost doGet中的数据将保存在该上下文中,因此可以安全地避免其他请求。

考虑到String vs StringBuffer vs StringBuilder,因为上下文本身是线程安全的,所以没有同步问题,所以你可以选择springbuilder。

旁注:如果没有发生变化,为什么不去寻找简单的字符串?

顺便说一句..请注意同一个文件的两个请求!!

答案 3 :(得分:0)

来自Java doc。

StringBuilder的实例不适合多线程使用。如果需要这样的同步,则建议使用StringBuffer。

http://download.oracle.com/javase/1.5.0/docs/api/java/lang/StringBuilder.html

首先,字符串是内化的。

http://download.oracle.com/javase/1,5.0/docs/api/java/lang/String.html#intern()

这意味着如果您有相同的字符串,则不是问题。

如果您的页眉和页脚是静态的,它可能是一个静态变量。

答案 4 :(得分:0)

如果你在一个方法中声明变量,它将被放入一个只能被当前线程访问的地方调用线程堆栈。所以你不必担心线程安全,只要它是局部变量 在你的情况下,你应该使用StringBuider,因为它更快,不需要担心线程安全

答案 5 :(得分:-1)

您的编码器是线程安全的,这在多线程环境中没有问题。因为您的ServleClass没有类级别或实例级别变量,所以FileWrite是post的方法中的Instance。 erver请求将有一个新的FileWrite ..