防止在我的应用程序中多次访问servlet

时间:2012-09-14 10:59:25

标签: java multithreading synchronization

下面给出了配置为autosys作业的URL。这会调用下面给出的servlet。任何人都可以建议我如何保护这个方法“psServiceWrapper.processHRFeed();”每次连续按下这个网址时,连续被称为不正确的数据修改被称为10次。我希望一次只访问一个线程。

我知道我必须使用同步方法或阻止..am不确定如何...因为我不熟悉线程。

http://mydomain:11000/dorf/HRDORFScriptServlet?script=hrFeed


public class HRDORFScriptServlet extends HttpServlet {

private static final long serialVersionUID = 1L;
private static final Logger log = Logger.getLogger(HRDORFScriptServlet.class);
private final String script = "script";

@Override
protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
    // TODO Auto-generated method stub
    performTask(arg0, arg1);
}

@Override
protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
    // TODO Auto-generated method stub
    performTask(arg0, arg1);
}

 /** Execute the servlet.
 * 
 * @param request
 * @param response
 * @throws ServletException
 * @throws IOException
 */
public void performTask(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {

    DorfUser dorfUser = DorfSessionUtils.getDorfUser(request.getSession());
    HRDorfFeedServiceWrapper psServiceWrapper = new HRDorfFeedServiceWrapper(dorfUser);
    String reqParam = request.getParameter(script);
    if(reqParam.equals("hrFeed")){
    try{
        psServiceWrapper.processHRFeed();           
    }
    catch(ServiceException se){
        log.error("Error While calling HRFeed Service : "+se.getMessage());
    }
    catch(Exception e){
        log.error("Error While calling HRFeed Service : "+e.getMessage());
    }

    }
 }

}

2 个答案:

答案 0 :(得分:3)

我会将psServiceWrapper.processHRFeed()的功能移动到一个实现Runnable的简单类。

public class MyTask implements Runnable
{
    public void run() 
    {
        psServiceWrapper.processHRFeed();
    }
}

然后创建一个固定线程池大小为1的ExecutorService。

ExecutorService psServiceRunner = Executors.newFixedThreadPool(1);

每次调用servlet时,我都会向此发布一个MyTask实例。

psServiceRunner.execute(new MyTask());

这将

  1. 不阻止您的servlet调用者。
  2. 确保只有一个servlet可以在任何时间运行该方法。

答案 1 :(得分:2)

synchronized(this){ 
 psServiceWrapper.processHRFeed();     
}

但是这将导致Bottleneck,因为你的servlet将停止响应,直到当前线程执行psServiceWrapper.processHRFeed();

如果您使用的是Java 5,也可以ReetrantLock

  

可重入互斥锁具有与使用同步方法和语句访问的隐式监视器锁相同的基本行为和语义,但具有扩展功能。

   private final ReentrantLock lock = new ReentrantLock();//Declare it

使用如下

 lock.lock();  // block until condition holds
 try {
   psServiceWrapper.processHRFeed();
 } finally {
   lock.unlock()
 }