2013-10-29 38 views
2

我花了數小時研究我的問題,但我找到了解決方案。如何通過返回Future來取消異步觸發的線程?

我用@Asynchronous註釋激發一個線程,並返回Future對象,到目前爲止效果很好。但是,如果我想取消未來,似乎命令不會取消任何內容。

JSF文件

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:h="http://xmlns.jcp.org/jsf/html"> 
    <h:head> 
     <title>Facelet Title</title> 
    </h:head> 
    <h:body> 
     <h:form> 
      <h:commandButton actionListener="#{threadHandler.start()}" value="start"/> 
      <h:commandButton actionListener="#{threadHandler.stop()}" value="stop"/> 
     </h:form> 
    </h:body> 
</html> 

的Java處理器

/* 
* To change this template, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package com.jsf.example; 

import java.util.concurrent.Future; 
import javax.ejb.Stateless; 
import javax.inject.Inject; 
import javax.inject.Named; 

@Named("threadHandler") 
@Stateless 
public class Handler { 

    Future future; 
    @Inject 
    MethodPool pool; 

    public void start(){ 
     System.out.println("start thread"); 
     future = pool.run(); 
     System.out.println("finish thread start"); 
    } 

    public void stop(){ 
     System.out.println("future.cancel " + future.cancel(true)); 
    } 
} 

Java線程

/* 
* To change this template, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package com.jsf.example; 

import java.util.concurrent.Future; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.ejb.AsyncResult; 
import javax.ejb.Asynchronous; 
import javax.ejb.Stateless; 


@Stateless 
public class MethodPool { 

    @Asynchronous 
    public Future run(){ 
     System.out.println("start run"); 
     Integer runCondition = 1; 
     while(runCondition > 0){ 
      try { 
       // simulate heavy stuff 
       Thread.sleep(1000); 
       System.out.println(". "); 
      } catch (InterruptedException ex) { 
       Logger.getLogger(MethodPool.class.getName()).log(Level.SEVERE, null, ex); 
      } 

     } 
     return new AsyncResult("finish run"); 
    } 

} 

* 編輯:THX @bkail *

我會後的工作代碼示例的下一個誰是絕望;)

@Resource 
    private SessionContext sessionContext; 

@Asynchronous 
    public Future run(){ 
     System.out.println("start run"); 
     while(sessionContext.wasCancelCalled() == false){ 
      try { 
       // simulate heavy stuff 
       Thread.sleep(1000); 
       System.out.println(". "); 
      } catch (InterruptedException ex) { 
       Logger.getLogger(MethodPool.class.getName()).log(Level.SEVERE, null, ex); 
      } 

     } 
     return new AsyncResult("finish run"); 
    } 

回答

4

EJB使用合作消除,所以通過取消(中斷=真)不實際上中斷。相反,它在方法調用上設置了一個標誌。在您的EJB中,使用@Resource SessionContext context;,然後檢查context.wasCancelCalled()以檢查是否調用cancel(interrupt = true)。

相關問題