javaweb学习总结二十三(servlet开发之线程安全问题)

时间:2023-03-09 19:56:26
javaweb学习总结二十三(servlet开发之线程安全问题)

一:servlet线程安全问题发生的条件

如果多个客户端访问同一个servlet时,发生线程安全问题,那么它们访问的是相同的资源。如果访问

的不是相同资源,则不存在线程安全问题。

javaweb学习总结二十三(servlet开发之线程安全问题)

实例1:不会产生线程安全问题,因为每个客户端发送请求,都会创建一个线程,都会创建一个count

不存在资源共享的问题。

1 public void doPost(HttpServletRequest request, HttpServletResponse response)
2 throws ServletException, IOException {
3 int count = 0;
4 count++;
5 response.getOutputStream().write((count + "").getBytes());
6 }

实例2:这种方式,多个线程公用资源,应该存在线程安全问题,但是我的测试结果一直不存在线程安全问题。有点不解?

 1 public class ServletDemo extends HttpServlet {
2
3 int count = 0;
4
5 public void doGet(HttpServletRequest request, HttpServletResponse response)
6 throws ServletException, IOException {
7 count++;
8 try {
9 Thread.sleep(1000 * 10);
10 } catch (InterruptedException e) {
11 e.printStackTrace();
12 }
13 response.getOutputStream().write((count + "").getBytes());
14 }
15
16 }

二:线程安全问题的处理

1:对于线程安全问题最简单的方式就是加锁:

将存在线程安全问题的代码放到同步代码块中,这样线程访问时就需要排队拿到钥匙,只有上一个

线程访问完毕,才会释放掉锁,先一个线程才可以进入。但是存在明显的缺点:就是效率太低了。

例如:门户网站日访问量过千万,效率太低了。

注意:应该尽量减少代码在同步代码块中

1 synchronized (this) {
2 count++;
3 try {
4 Thread.sleep(1000 * 10);
5 } catch (InterruptedException e) {
6 e.printStackTrace();
7 }
8 response.getOutputStream().write((count + "").getBytes());
9 }

2:实现singleThreadModel接口

servlet实现singleThreadModel接口后,每个线程都会创建servlet实例,这样每个客户端请求就不存在共享资源的问题

,但是servlet响应客户端请求的效率太低,所以已经淘汰。