首页 > 其他 > 详细

servlet 单例问题

时间:2015-04-01 00:06:33      阅读:162      评论:0      收藏:0      [点我收藏+]

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("對不起,已經沒有票了");
            }
        }

 

servlet 单例问题

原文:http://www.cnblogs.com/zhang-tech/p/4382467.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!