关于servlet的线程安全性有很多问题,但我想问一下servlet使用的其他类。
在普通应用程序中,servlet 类也使用其他普通类(我的应用程序就是这样),就像在 MVC 中一样。所以我的问题是我应该将模型类中的所有函数声明为同步
假设我有 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
应该
不为空。
所以,
- 所有功能是否应该同步
- 是否应该同步所有使用静态变量的函数
- 是否应该仅使用静态函数进行同步
- 是否应该只同步使用静态变量的静态函数
最佳答案
在 servlet 中,使用静态变量通常是糟糕的设计......并且可能是一个错误......。但是,如果您确实使用(并且需要使用)静态变量,那么访问和更新它们的代码将需要正确同步。 (Servlet 代码在多个线程上执行……除非您仅通过配置一个工作线程来阻碍 Web 容器框架。)
如果做得正确,将方法声明为同步
是实现此目的的一种方法。
但是...
简单地声明要同步
的方法是一个坏主意。在开始添加同步之前,您需要了解代码的预期并发模式。盲目添加synchronized
可能会导致并发瓶颈和潜在的死锁。 (如果互斥的粒度不适合该问题,您仍然可能会遇到线程安全问题。)
我同意@Roman C的回答。您不应该尝试在多个请求之间共享相同的数据库连接......如果这就是您实际上正在做的事情。我建议您考虑使用数据库连接池。
关于java - Servlet 中的线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25176514/