【发布时间】:2014-07-22 04:28:35
【问题描述】:
我知道在 servlet 过滤器中我们应该注意我们的实例变量的线程安全,但是在下面的代码中,我使用了 stringBuilder 和 stringBuffer(一个线程安全,一个不安全)。
public class ValidationFilter implements Filter {
//thread safe
// StringBuffer request=new StringBuffer();
//not thread safe--lets check if it works fine
StringBuilder request=new StringBuilder();
////NOTE!!!:even with large request lenght no interference was seen so what is the problem with NOT being thread safe??
@Override
public void init(FilterConfig config) throws ServletException {
//
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
//HERE WE PUT SOME CODE REGARDING TO FILTERING REQUESTS
//HERE WE SHOULD DEFINE A REGEX TO VALIDATE THE STRING IF IT IS NOT THE RIGHT STRING REDIRECT THE REQUEST TO A NEW ADDRESS!!
//String is immutable so we need to use string buffer or string builder
//StringBuffer is synchronized, StringBuilder is not. BUT as far as we know Servlet creates new thread for each request fo we
//need to be synchronised!!
request.append(req.getParameter("line"));
System.out.print(request);
if (request!=null){
Token.trim(request.toString());
res.getWriter().print(request);
}else {
res.getWriter().print("Error got Null from the client!");
}
}
@Override
public void destroy() {
//
}
}
在这两种情况下,我都使用如下表单发送了一个非常长的请求(实际上通过使用此表单,我发送了两个非常长的请求输入),但我们得到了上述过滤器的输出,我看不到两者之间有任何干扰输出结果意味着这两个线程安全运行并且没有破坏 StringBuffer 或 StringBulder ,所以这意味着在这种情况下线程安全吗??
<!DOCTYPE html>
<html>
<head>
<title>a request page</title>
</head>
<body>
<form action="http://localhost:8080/Compute" method="POST">
Compute it: <input type="text" name="line"><p>
<input type="submit" value="Compute">
</form>
</body>
</html>
【问题讨论】:
-
为什么要在
doFilter方法中修改过滤器本身的状态根本?无论您使用哪种类型,这似乎都是个坏主意。 (甚至StringBuffer在同步操作方面也只是“安全”的——这并不意味着您可以在多个独立操作之间有效地共享一个实例。) -
您的整个代码毫无意义。
request永远不会是null,因此您的支票已过时。如果你想测试req.getParameter("line")的返回值对于null你必须这样做;将其附加到StringBuilder不会将StringBuilder变为null。此外,您仍然将不可变的String传递给Token.trim(…),因此StringBuilder的可变性在这里无关紧要。无论Token.trim(…)做什么,都不会影响您的StringBuilder。
标签: java multithreading servlets servlet-filters