【问题标题】:How to cancel a asynchronously fired thread with returning Future?如何取消返回 Future 的异步触发线程?
【发布时间】:2013-10-29 09:15:07
【问题描述】:

我花了数小时研究我的问题,但我找到了解决方案。

我用@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");
    }

}

*编辑:谢谢@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");
    }

【问题讨论】:

    标签: java multithreading jsf asynchronous ejb-3.1


    【解决方案1】:

    EJB 使用协作取消,因此传递 cancel(interrupt=true) 实际上不会中断。相反,它在方法调用上设置一个标志。在您的 EJB 中,使用 @Resource SessionContext context;,然后检查 context.wasCancelCalled() 以检查是否调用了 cancel(interrupt=true)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-01
      • 2019-10-08
      • 2017-07-28
      • 1970-01-01
      • 2015-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多