Java servlet中的线程安全
关于servlet的线程安全性有很多问题,但我想问一下servlet使用的其他类 在一个普通的应用程序中,servlet类也使用其他普通类(我的appl-do),就像在MVC中一样。所以我的问题是我是否应该将模型类中的所有函数声明为synchronized 假设我有2个servlet,使用类Dog和Cat。这两个类都有一些静态和非静态函数以及静态和非静态变量 这些方法使用数据库连接来显示内容,我得到了这段代码的Java servlet中的线程安全,java,servlets,jdbc,thread-safety,synchronized,Java,Servlets,Jdbc,Thread Safety,Synchronized,关于servlet的线程安全性有很多问题,但我想问一下servlet使用的其他类 在一个普通的应用程序中,servlet类也使用其他普通类(我的appl-do),就像在MVC中一样。所以我的问题是我是否应该将模型类中的所有函数声明为synchronized 假设我有2个servlet,使用类Dog和Cat。这两个类都有一些静态和非静态函数以及静态和非静态变量 这些方法使用数据库连接来显示内容,我得到了这段代码的nullpointerexception try { Connection
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)
socon
应该
不能为空
所以
在servlet中,它通常是糟糕的设计。。。可能是个错误。。。有静态变量。但是如果您确实使用(并且需要使用)静态变量,那么访问和更新它们的代码就需要正确地同步。(Servlet代码在多个线程上执行……除非您仅配置一个工作线程而使web容器框架步履蹒跚。) 如果操作正确,将方法声明为
synchronized
是实现这一点的一种方法
然而
仅仅随意地将方法声明为同步
是个坏主意。在开始添加同步之前,您需要了解代码的预期并发模式。盲目添加同步的
会导致并发瓶颈和潜在的死锁。(如果互斥的粒度不适合这个问题,那么仍然可能存在线程安全问题。)
我同意@Roman C的回答。您不应尝试在多个请求之间共享同一数据库连接。。。如果这是你真正在做的。我建议您考虑使用数据库连接池。在servlet中,它通常是糟糕的设计。。。可能是个错误。。。有静态变量。但是如果您确实使用(并且需要使用)静态变量,那么访问和更新它们的代码就需要正确地同步。(Servlet代码在多个线程上执行……除非您仅配置一个工作线程而使web容器框架步履蹒跚。) 如果操作正确,将方法声明为
synchronized
是实现这一点的一种方法
然而
仅仅随意地将方法声明为同步
是个坏主意。在开始添加同步之前,您需要了解代码的预期并发模式。盲目添加同步的
会导致并发瓶颈和潜在的死锁。(如果互斥的粒度不适合这个问题,那么仍然可能存在线程安全问题。)
我同意@Roman C的回答。您不应尝试在多个请求之间共享同一数据库连接。。。如果这是你真正在做的。我建议您考虑使用数据库连接池。不要在其他类中使用static。那么您就不必担心线程安全,JDBCAPI会注意的。但是如果您在servlet之间共享一些对象,比如在某个上下文中,那么您应该同步访问它的容器。这就是使用一些基于servlet技术的框架的原因,这些框架是为了帮助您更好地使用其他对象并以线程安全的方式使用它们而创建的。原始servlet功能强大,但您必须解决自己在尝试重新发明轮子时遇到的问题
关于异常捕获,它可以在第一个语句中抛出,因此
con
对象保持未初始化状态。手动管理连接(如果有的话)不是一个好方法,因为您在同步连接时遇到了同样的问题。作为JDBC的一个标准,它为您提供了通过池管理连接的API,因此您不必重新发明轮子来提供您自己的同步方法 不要在其他类中使用static。那么您就不必担心线程安全,JDBCAPI会注意的。但是如果您在servlet之间共享一些对象,比如在某个上下文中,那么您应该同步访问它的容器。这就是使用一些基于servlet技术的框架的原因,这些框架是为了帮助您更好地使用其他对象并以线程安全的方式使用它们而创建的。原始servlet功能强大,但您必须解决自己在尝试重新发明轮子时遇到的问题
关于异常捕获,它可以在第一个语句中抛出,因此
con
对象保持未初始化状态。手动管理连接(如果有的话)不是一个好方法,因为您在同步连接时遇到了同样的问题。作为JDBC的一个标准,它为您提供了通过池管理连接的API,因此您不必重新发明轮子来提供您自己的同步方法 您向我们展示的代码显然是“虚构的”,因此我认为试图找出它为什么不“工作”是没有成效的。但有一种可能是你只是误解了stacktrace。在你的真实代码中,“con”是一个静态变量吗?是的,谢谢你指出,我错误地将con用作静态变量。你展示给我们的代码显然是“虚构的”,所以我不认为试图弄清楚为什么它“不起作用”是有效的。但有一种可能性是,您只是误解了stacktrace