我必须知道我的servlet中存在争用条件,因为我在其中使用了一些全局声明的变量。所以我的问题是,如果我在某种方法中使用doGet
或doPost
方法声明这些变量。它们不会在不同的线程之间共享吗?
如果是的话,我们如何才能避免种族问题。我想避免使用ThreadLocal
和使用singelThreadModel
。
以下是示例
public class UserServlet extends HttpServlet {
private String userString1 = "";
private String userString2 = "";
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
someTask(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
someTask(request, response);
}
public void someTask(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
userString1 = request.getParameter("someParameter");
userString2 = request.getParameter("someParameter");
}
}
注意:这只是一个示例,而不是实际代码。
答案 0 :(得分:0)
servlet中声明的方法是否是线程安全的
没有
或servlet中的局部变量是线程安全的
没有
我必须知道我的servlet中存在种族问题
种族条件。
因为我在其中使用了一些全局声明的变量。
您有一些实例变量。
所以我的问题是,如果我在某种方法中使用
-Path C:\Temp\
或doGet()
方法声明这些变量,它们是否会在不同的线程之间共享?
局部变量是声明它们的方法的本地变量。
如果是的话,我们怎样才能避免因种族问题而竞争。
我不能跟随你的双重否定,但它仍然是种族条件。不要滥用标准术语。您需要避免doPost()
的实例成员,除非它们对其方法的所有可能的并发调用是共同的并且共享。每个请求变量必须是方法本地的,并在方法之间作为参数或返回值传递。
我希望避免使用
Servlet
和使用ThreadLocal
。
你当然可以。 SingleThreadModel
中没有指定的线程语义可以使Servlet
正常工作,ThreadLocal
已弃用且将被删除。
答案 1 :(得分:0)
Servlet是一个Java类,因此如果它没有状态(即它没有任何状态变量),它已经是线程安全的。您无需采取额外措施。
现在,您要引入状态变量,例如 - userString1
& userString2
并且您的servlet仍然可以是线程安全的,因为String
是不可变的,但是您为每个请求重新分配其引用,因此它不会保持线程安全,因为一个线程的赋值可能会更改为其他值一些其他线程(当时,线程尝试使用它)。你可以拥有一个不可变的状态&保持线程安全,前提是您不要像someTask
方法那样重新分配其引用。
因此,使用这些字符串变量,其目的是将一些常量字符串传递给所有请求线程。
此外,在您的代码中,您通过someTask
方法中的赋值表达式在堆上放置了大量字符串。
最后,如果必须在这些方法中使用可变状态对象,则必须利用java同步构造来使类线程安全,但是每个JVM再次使用普通Java同步构造,因此如果必须分发部署,则会遇到问题在群集上。在这种情况下将需要一些分布式锁定机制。
答案 2 :(得分:0)
如果要声明全局变量并在doGet或doPost方法中分配值,则它们肯定会被调用servlet的不同线程覆盖。 不应该在servlet方法调用中为全局变量赋值。
在您的代码中阻止您声明userString1
& userString2
里面的方法?为什么要在全球范围内声明它们?如果您希望在servlet的不同方法中使用这些变量,那么只需将它们作为方法参数传递,而不是将它们声明为全局变量。
e.g。
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userString1 = request.getParameter("someParameter");
String userString2 = request.getParameter("someParameter");
someTask(request, response, userString1, userString2);
}
public void someTask(HttpServletRequest request, HttpServletResponse response, String userString1, String userString2) throws ServletException, IOException {
//do whatever you want with these variables.
}
或强>
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
someTask(request, response);
}
public void someTask(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userString1 = request.getParameter("someParameter");
String userString2 = request.getParameter("someParameter");
//do whatever you want with these variables.
}