如何使用停止按钮停止运行Java代码

我有一个按钮从调用Bean调用方法。 此方法允许从解析html代码中提取数据。 当该方法运行时,我有一个对话框,显示进度条和命令按钮Cancel 。 我需要当用户单击取消按钮时,提取按钮调用的方法停止。

这是我的HTML代码:

 

这是我的sessionScoped Bean中的searchEmails方法

  public void searchEmails() throws Exception { idCustomer = (String) session.getAttribute("idCustomer"); System.out.println(idCustomer + " this is it"); Customer customer = customerBusinessLocal.findById(idCustomer); data = dataBusinessLocal.createData(new Date(), number, keyword, moteur, customer, State.REJECTED); mails = mailBusinessLocal.createEmails(keyword, number, moteur, data); System.out.println("Method was invoked"); } 

如何通过取消命令按钮停止searchEmails方法的运行?

具有中断友好任务的ExecutorService

ExecutorService文档


  • 而不是直接调用该方法,将该方法转换为ExecutorService的任务。

     public class SearchEmailsTask implements Runnable { private EmailSearcher emailSearcher; public SearchEmailsTask(EmailSearcher emailSearcher) { this.emailSearcher = emailSearcher; } @Override public void run() { emailSearcher.searchEmails(); } } 

    如果要返回某些内容,可以使用Callable


  • 如果要调用方法,请将该任务提交给ExecutorService

     ExecutorService executorService = Executors.newFixedThreadPool(4); SearchEmailsTask searchEmailsTask = new SearchEmailsTask(new EmailSearcher()); Future future = executorService.submit(searchEmailsTask); 

  • 保留对任务的引用。

     private static Map > results = new HashMap >(); 

    存储多个Future对象的地图应该是一个好主意。 如果你愿意,你当然可以选择更好的东西。


  • 必要时,呼叫取消任务。

     future.cancel(true); 

注意:
任务应该有适当的线程中断检查以正确取消。
要实现此目的,请参阅

  1. ExecutorService的未来任务并未真正取消
  2. 如何使用线程的id挂起线程?

祝你好运。

使用您当前的架构并不容易。 通过查看您的代码,您似乎在调用两个不能在中间中止的大型操作。 您必须将工作分解为小单元并使处理中止。

使用当前代码的最简单的解决方案可能看起来像这样。

  public class SessionScopedMailBean { volatile boolean searchAborted; public void searchEmails() throws Exception { searchAborted = false; while(!searchAborted) { // Process a single unit of work } } public void abortSearch() { searchAborted = true; } } 

在JSF中:

  

这就是说我建议使用执行器和基于期货的方法来实现更清洁的架构。 然后你也可以实现一个真正的进度条而不仅仅是一个动画GIF微调器。

在命令处理程序中执行长操作的另一个问题是最终HTTP请求将超时。

一个更干净的解决方案将如下所示:

 public class SessionScopedBean { ExecutorService pool; List> pendingWork; @PostConstruct public void startPool() { pool = Executors.newFixedThreadPool(1); } @PreDestroy public void stopPool() { if(executor != null) pool.shutdownNow(); } public void startSearch() { pendingWork = new ArrayList>(); // Prepare units of work (assuming it can be done quickly) while(/* no more work found */) { final MyType unit = ...; // Determine next unit of work Callable worker = new Callable() { @Override public Void call() throws Exception { // Do whatever is needed to complete unit } }; pendingWork.add(pool.submit(worker)); } } public int getPending() { int nPending = 0; for(Future i: pendingWork) if(!i.isDone()) nPending++; return nPending; } public void stopSearch() { for(Future i: pendingWork) if(!i.isDone()) i.cancel(true); } } 

然后使用AJAX轮询组件轮询getPending以确定何时完成并隐藏窗口。

也可以看看:

Interesting Posts