java - Servlet 中的线程安全

标签 java servlets jdbc thread-safety synchronized

关于servlet的线程安全性有很多问题,但我想问一下servlet使用的其他类。

在普通应用程序中,servlet 类也使用其他普通类(我的应用程序就是这样),就像在 MVC 中一样。所以我的问题是我应该将模型类中的所有函数声明为同步

enter image description here

假设我有 2 个 servlet,并且使用类 Dog 和 Cat。这两个类都有一些静态和非静态函数以及静态和非静态变量。

这些方法使用数据库连接来显示内容,我在这段代码中遇到了nullpointerexception

try {
    Connection con = DriverManager.getConnection(url, user, pass);
    Statement stmt =  con.createStatement();
    select = "SELECT * FROM table";
    java.sql.ResultSet result = stmt.executeQuery(select);
    while(result.next())
    {
        do something
    }
} 
catch (SQLException e) {
    e.printStackTrace();
} 
finally {
    if (con != null) 
        try {
            con.close();
        } 
        catch (Exception e) {
            e.printStackTrace();
        }
}

令我惊讶的是,我在 try { con.close(); 行中得到了异常} : nullPointerException 据我了解,因为我已经检查过 if (con != null) 所以 con 应该 不为空。

所以,

  1. 所有功能是否应该同步
  2. 是否应该同步所有使用静态变量的函数
  3. 是否应该仅使用静态函数进行同步
  4. 是否应该只同步使用静态变量的静态函数

最佳答案

在 servlet 中,使用静态变量通常是糟糕的设计......并且可能是一个错误......。但是,如果您确实使用(并且需要使用)静态变量,那么访问和更新它们的代码将需要正确同步。 (Servlet 代码在多个线程上执行……除非您仅通过配置一个工作线程来阻碍 Web 容器框架。)

如果做得正确,将方法声明为同步是实现此目的的一种方法。

但是...

简单地声明要同步的方法是一个坏主意。在开始添加同步之前,您需要了解代码的预期并发模式。盲目添加synchronized可能会导致并发瓶颈和潜在的死锁。 (如果互斥的粒度不适合该问题,您仍然可能会遇到线程安全问题。)


我同意@Roman C的回答。您不应该尝试在多个请求之间共享相同的数据库连接......如果这就是您实际上正在做的事情。我建议您考虑使用数据库连接池。

关于java - Servlet 中的线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25176514/

相关文章:

java - FindBugs 说我需要 "use a prepared statement"?如何?

java - 当我更新多对多关系时,所有记录都获得相同的值

java - Java 中的多线程帮助

java - ClassCastException 冒险

java - 对对象的 ArrayList 进行排序

java - 奇怪的 SQLException - 无法检索事务只读状态服务器

java线程和同步

java - 在页面加载时从 JSP 文件调用 servlet

java - 当用户从资源类访问资源时,Rest Service 将如何执行?

java - 如何从 HTML 表单调用 servlet