5

下面给出的是配置为autosys作业的url。这调用下面给出的servlet。谁能建议我如何保护这个方法“psServiceWrapper.processHRFeed();” 每次连续按下此 url 时,由于不正确的数据修改而被连续调用 10 次。我希望一次只能访问一个线程。

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

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());
    }

    }
 }

}

4

2 回答 2

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 可以运行该方法。
于 2012-09-14T11:30:57.327 回答
2
synchronized(this){ 
 psServiceWrapper.processHRFeed();     
}

但这将导致瓶颈,因为您的 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()
 }
于 2012-09-14T11:03:58.570 回答