Servlet学习----servlet的线程并发问题

73 篇文章 0 订阅
26 篇文章 0 订阅

servlet对象在tomcat服务器是单实例多线程的。

因为servlet是多线程的,所以当多个servlet的线程同时访问了servlet的共享数据,如成员变量,可能会引发线程安全问题。

package com.loaderman.demo;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class TestServlet extends HttpServlet {

    int count = 1;

    //servlet的多线程并发问题
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");

            response.getWriter().write("你现在是当前网站的第" + count + "个访客");   //线程1执行完  , 线程2执行

            //线程1还没有执行count++
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            count++;
        
    }
}

解决方法: 

1.同步代码块:给使用到共享数据的代码块添加同步锁

          注:同步锁必须多个线程唯一

package com.loaderman.demo;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class TestServlet extends HttpServlet {

    int count = 1;

    //servlet的多线程并发问题
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");

        synchronized (TestServlet.class) {//锁对象必须唯一。建议使用类对象
            response.getWriter().write("你现在是当前网站的第" + count + "个访客");   //线程1执行完  , 线程2执行

            //线程1还没有执行count++
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            count++;
        }
    }
}

2.同步方法 

package com.loaderman.demo;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class TestServlet extends HttpServlet {

    int count = 1;

    //servlet的多线程并发问题
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        method(response);
    }

    public synchronized static void method(HttpServletResponse response){
         try{
               response.getWriter().write("你现在是当前网站的第" + count + "个访客");
          }catch (IOExcetion e1) {
               e1.printStackTrace();
         }
          try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            count++;
   }
}

开发线程安全的servlet建议:

  • 尽量不要使用成员变量,或者静态成员变量
  • 必须要使用成员变量时,要么使用了成员变量的代码块加同步锁,加锁的代码块的范围尽量缩小,因为有可能影响程序并发效率。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值