servlet 单例问题

servlet是单例的,即在web服务器中最多只存在servlet的一个实例,那么servlet就是线程不安全的。下面通过以下代码模拟买票过程:

package com.zjb.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyServlet1 extends HttpServlet {
    private int ticket = 2;

    /**
     * The doGet method of the servlet. <br>
     * 
     * This method is called when a form has its tag value method equals to get.
     * 
     * @param request
     *            the request send by the client to the server
     * @param response
     *            the response send by the server to the client
     * @throws ServletException
     *             if an error occurred
     * @throws IOException
     *             if an error occurred
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        // out.println("hello,I am the first Myeclipse servlet,the currentTime is "
        // + new Date().toString());
        if(ticket>0){
            System.out.println("恭喜你,买到票了");
            try {
                Thread.sleep(10*1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            ticket--;
        }else{
            System.out.println("對不起,已經沒有票了");
        }
        out.close();
    }

    /**
     * The doPost method of the servlet. <br>
     * 
     * This method is called when a form has its tag value method equals to
     * post.
     * 
     * @param request
     *            the request send by the client to the server
     * @param response
     *            the response send by the server to the client
     * @throws ServletException
     *             if an error occurred
     * @throws IOException
     *             if an error occurred
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doGet(request, response);
    }

}

从上面代码可以看出,现在一共有2张票,即只有2个请求可以买到票,然而当从浏览器发出三次请求是却出现了下面的结果:

那么,这种由单例造成的线程不安全问题该如何解决呢?只要把操作共享资源(如ticket)的代码加同步锁即可:

synchronized (this) {
            if(ticket>0){
                System.out.println("恭喜你,买到票了");
                try {
                    Thread.sleep(10*1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                ticket--;
            }else{
                System.out.println("對不起,已經沒有票了");
            }
        }

 

转载于:https://www.cnblogs.com/zhang-tech/p/4382467.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值