java - 如何防止多个 Servlet 线程同时访问静态方法

标签 java multithreading servlets synchronization

这是我使用的代码
删除和重命名目录中的大量文件。

protected void doPost(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {
    response.setContentType("text/html; charset=UTF-8");
    response.setCharacterEncoding("UTF-8");
    RootSipResourceApp.updateRootFile(strDirectorypath, strappID, appNames);
    RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/index.jsp");
    dispatcher.forward(request, response);
}

public static void updateRootFile(String directorypath, String appID, String[] appName) 
  throws IOException {
    try {
        FileInputStream fin = null;
        File[] listOfFiles=fileLists(directorypath);
        for (int i = 0; i < listOfFiles.length; i++) {
            if (listOfFiles[i].isFile()) {
                rootFiles = listOfFiles[i].getName();
                if (rootFiles.endsWith(".properties") || rootFiles.endsWith(".PROPERTIES")) {
                    fin = new FileInputStream(directorypath + rootFiles);
                    properties.load(new InputStreamReader(fin, Charset.forName("UTF-8")));
                    String getAppName = properties.getProperty("root.label." + appID);
                    String propertyStr = "root.label." + appID;
                    saveFile(fin, getAppName, directorypath + rootFiles, propertyStr, appName[i]);
                }
            }
        }
    } catch (Exception e) {
        System.out.println("expn-" + e);
    }
}

public static void saveFile(FileInputStream fins, String oldAppName, String filePath, String propertyStr, String appName)
  throws IOException {
    String oldChar = propertyStr + "=" + oldAppName;
    String newChar = propertyStr + "=" + appName;
    String strLine;
    File f1 = new File(filePath);
    File f2 = new File("C:\\Equinox\\RootSipResource\\root\\root_created.properties");
    BufferedReader br = new BufferedReader(new InputStreamReader( new FileInputStream(f1), "UTF-8"));
    OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(f2), "UTF-8");
    while ((strLine = br.readLine()) != null) {
        strLine = strLine.replace(oldChar, newChar);
        out.write(strLine);
        out.write("\r\n");
    }
    out.flush();
    out.close();
    br.close();
    fins.close();
}

最佳答案

选项 1:

public static void updateRootFile更改为public static synchronized void updateRootFile

选项 2:

添加成员到servlet类

private final static Object lock = new Object();

然后将 updateRootFile 方法中的代码包装到

synchronized(lock) {
   ....
}

不同之处在于选项 1 锁定整个 servlet 类(所有它的同步方法),而选项 2 允许从除 updateRootFile() 之外的其他线程调用其他 servlet 的方法

我相信最权威的指南之一 is here .第 07 - 11 章与多线程代码相关。

关于java - 如何防止多个 Servlet 线程同时访问静态方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8600827/

相关文章:

java - 如何使用 Servlet 在 Java 应用程序中实现 OAuth2 SSO?

java - 无法将 HashSet 解析为 JSONObject 字符串

java - 使 JavaFX 应用程序线程等待另一个线程完成

java - 生成 Html5Manifest 文件时 MGWT 中的 "javax.servlet.ServletException: unkown device"

c++ - 一个线程的windows非取消模式

java - 如何减少java中大文件日志分析的时间

java - 如何在 servlet 过滤器中重定向?

java - 无法访问 Spring Boot 和 Jersey 应用程序中的某些 Controller

java - 返回泛型类类型

java - 在同一个类的方法中使用封装getter