Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 防止在我的应用程序中多次访问servlet_Java_Multithreading_Synchronization - Fatal编程技术网

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

Java 防止在我的应用程序中多次访问servlet,java,multithreading,synchronization,Java,Multithreading,Synchronization,下面给出的是配置为autosys作业的url。这将调用下面给出的servlet。有人能建议我如何保护此方法“psServiceWrapper.processHRFeed();”在每次不正确地修改数据时被不断调用,比如说10次。我希望一次只能访问一个线程 我知道我必须使用同步方法或块..我不确定如何..因为我不太熟悉线程 http://mydomain:11000/dorf/HRDORFScriptServlet?script=hrFeed public class HRDORFScriptS

下面给出的是配置为autosys作业的url。这将调用下面给出的servlet。有人能建议我如何保护此方法“psServiceWrapper.processHRFeed();”在每次不正确地修改数据时被不断调用,比如说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());
    }

    }
 }
}

但这将导致瓶颈,因为servlet将在
psServiceWrapper.processHRFeed()之前停止响应由当前线程执行

如果您使用的是Java5,您也可以这样做

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

像下面那样使用它

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

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

public class MyTask implements Runnable
{
    public void run() 
    {
        psServiceWrapper.processHRFeed();
    }
}
然后创建一个固定线程池大小为1的ExecutorService

ExecutorService psServiceRunner = Executors.newFixedThreadPool(1);
每次调用servlet时,我都会将MyTask的一个实例发布到这个servlet

psServiceRunner.execute(new MyTask());
这将

  • 不要阻止servlet调用程序
  • 确保在任何时间点只有一个servlet可以运行该方法

  • 本文中提到的序列化访问确实会解决您的问题,但会以牺牲应用程序的活力为代价。您的实际问题是processHRFeed()方法不是并发的。如果性能在您的项目中有意义,并且您可以访问该方法的实现(即如果您可以修改它),我建议您调查是否可以重新设计该方法,以便通过并发线程安全地运行。
    ExecutorService psServiceRunner = Executors.newFixedThreadPool(1);
    
    psServiceRunner.execute(new MyTask());