如何保证 Controller 的并发安全?
Each incoming request requires a thread for the duration of that request. If more simultaneous requests are received than can be handled by the currently available request processing threads, additional threads will be created up to the configured maximum (the value of the maxThreads attribute). If still more simultaneous requests are received, they are stacked up inside the server socket created by the Connector, up to the configured maximum (the value of the acceptCountattribute). Any further simultaneous requests will receive "connection refused" errors, until resources are available to process them. —— https://tomcat.apache.org/tomcat-7.0-doc/config/http.html
Controller不是线程安全的
@Controller
public class TestController {
private int num = 0;
@RequestMapping("/addNum")
public void addNum() {
System.out.println(++num);
}
}
首先访问 http:// localhost:8080 / addNum
,得到的答案是1;再次访问 http:// localhost:8080 / addNum
,得到的答案是 2。
Controller并发安全的解决办法
尽量不要在 Controller 中定义成员变量 ;
@Scope(“prototype”)
,将Controller设置为多例模式。@Controller
@Scope(value="prototype")
public class TestController {
private int num = 0;
@RequestMapping("/addNum")
public void addNum() {
System.out.println(++num);
}
}
Controller 中使用 ThreadLocal 变量。每一个线程都有一个变量的副本。
public class TestController {
private int num = 0;
private final ThreadLocaluniqueNum =
new ThreadLocal() {
@Override protected Integer initialValue() {
return num;
}
};
@RequestMapping("/addNum")
public void addNum() {
int unum = uniqueNum.get();
uniqueNum.set(++unum);
System.out.println(uniqueNum.get());
}
}
http:// localhost:8080 / addNum
, 得到的结果都是1。推荐阅读:
内容包含Java基础、JavaWeb、MySQL性能优化、JVM、锁、百万并发、消息队列、高性能缓存、反射、Spring全家桶原理、微服务、Zookeeper......等技术栈!
⬇戳阅读原文领取! 朕已阅
评论