无法取消对 EJB 的 @Asynchronous 调用

2024-02-10

在这个最简单的例子中我做错了什么? (Glassfish 4.0-b87 + Eclipse 开普勒 m6)

我自己.java

package com.example.cancelbug;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.inject.Inject;

@Singleton
@Startup
public class Myself {
  @Inject Other other;
  private Future < Integer > future;

  @PostConstruct
  public void post_construct () {
    System.out.println("post_construct started");
    future = other.ton_of_work();
    System.out.println("post_construct ended");
  }

  @PreDestroy
  public void pre_destroy () {
    System.out.println("pre_destroy started");
    System.out.println("cancel result: " + Boolean.toString(future.cancel(true)));
    try {
      System.out.println("future result: " + future.get().toString());
    } catch (InterruptedException | ExecutionException e) {
      System.out.println("future result: interrupted");
      Thread.currentThread().interrupt();
      System.out.println("thread reinterrupted");
    }
    System.out.println("pre_destroy ended");
  }
}

其他.java

package com.example.cancelbug;

import java.util.concurrent.Future;

import javax.ejb.AsyncResult;
import javax.ejb.Asynchronous;
import javax.ejb.Stateless;

@Stateless
public class Other {
  @Asynchronous
  public Future < Integer > ton_of_work () {
    System.out.println("other: ton_of_work started");
    int i;
    for (i = 0; i < 10; ++i) {
      try {
        System.out.println("other: take a nap");
        Thread.sleep(1000L);
        System.out.println("other: woke up: " + Integer.toString(i));
      } catch (InterruptedException e) {
        System.out.println("other: ton_of_work interrupted");
        Thread.currentThread().interrupt();
        break;
      }
    }
    System.out.println("other: ton_of_work returning");
    return new AsyncResult < Integer >(new Integer(i));
  }
}

Output

post_construct started
post_construct ended
other: ton_of_work started
other: take a nap
other: woke up: 0
other: take a nap
other: woke up: 1
other: take a nap
other: woke up: 2
other: take a nap
pre_destroy started
cancel result: false            <<<<<<< expected true; ton_of_work: interrupted
other: woke up: 3               <<<<<<< expected no such output
other: take a nap               <<<<<<< expected no such output
other: woke up: 4               <<<<<<< expected no such output
other: take a nap               <<<<<<< expected no such output
other: woke up: 5               <<<<<<< expected no such output
other: take a nap               <<<<<<< expected no such output
other: woke up: 6               <<<<<<< expected no such output
other: take a nap               <<<<<<< expected no such output
other: woke up: 7               <<<<<<< expected no such output
other: take a nap               <<<<<<< expected no such output
other: woke up: 8               <<<<<<< expected no such output
other: take a nap               <<<<<<< expected no such output
other: woke up: 9               <<<<<<< expected no such output
other: ton_of_work returning
future result: 10               <<<<<<< expected 2
pre_destroy ended

预期输出:

post_construct started
post_construct ended
other: ton_of_work started
other: take a nap
other: woke up: 0
other: take a nap
other: woke up: 1
other: take a nap
other: woke up: 2
other: take a nap
pre_destroy started
cancel result: true             <<<<<<< actual false
other: ton_of_work interrupted  <<<<<<< actual missing
other: ton_of_work returning
future result: 2                <<<<<<< actual 10
pre_destroy ended

EJB 3.1仅提供协作异步中断;也就是说,EJB 可以检查客户端是否调用了cancel。即使调用 Future.cancel(true) 也无法获得实际的 Thread.interrupt。

存在一个开放的 EJB 规范问题(EJB_SPEC-73 https://java.net/jira/browse/EJB_SPEC-73)以允许实际的线程中断。 EJB 3.2 专家组对此进行了讨论(1 https://java.net/projects/ejb-spec/lists/jsr345-experts/archive/2012-09/message/7, 2 https://java.net/projects/ejb-spec/lists/jsr345-experts/archive/2012-10/message/7, 3 https://java.net/projects/ejb-spec/lists/jsr345-experts/archive/2012-10/message/9, 4 https://java.net/projects/ejb-spec/lists/jsr345-experts/archive/2012-12/message/29, 5 https://java.net/projects/ejb-spec/lists/jsr345-experts/archive/2013-01/message/32, 6 https://java.net/projects/ejb-spec/lists/jsr345-experts/archive/2013-03/message/47),但讨论最终被推迟到 EJB 规范的下一版本。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无法取消对 EJB 的 @Asynchronous 调用 的相关文章

随机推荐