无法取消对EJB的异步调用 [英] Cannot Cancel @Asynchronous call to EJB

查看:129
本文介绍了无法取消对EJB的异步调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



Myself.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其他;
private 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:interrup);
Thread.currentThread()。interrupt();
System.out.println(thread reinterrupted);
}
System.out.println(pre_destroy terminated);
}
}

Other.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其他{
@Asynchronous
public Future<整数> 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 blocked);
Thread.currentThread()。interrupt();
break;
}
}
System.out.println(other:ton_of_work returned);
返回新的AsyncResult<整数>(new Integer(i));
}
}

输出

  post_construct开始
post_construct结束
其他:ton_of_work开始
其他:小睡
其他:醒来:0
其他:小睡
其他:醒来:1
其他:小睡
其他:醒来:2
其他:小睡
pre_destroy started
cancel result:false<<<<<<<预期真实ton_of_work:打断
其他:醒来:3<<<<<预期没有这样的输出
其他:休息<<<<<<预期没有这样的输出
其他:唤醒:4 < - <<<<预期没有这样的输出
其他:休息<<<<<<预期没有这样的输出
other:woke up:5 <= <<<<预期没有这样的输出
其他:休息<<<<<<预期没有这样的输出
其他:醒来:6 < - << <<预期没有这样的输出
其他:休息<<<<<<预期没有这样的输出
其他:唤醒:7 其他:休息<<<<<<预期没有这样的输出
other:woke up:8 <= <<<<预期没有这样的输出
其他:休息<<<<<<预期没有这样的输出
其他:醒来:9 < - <<<<期望没有这样的输出
其他:ton_of_work返回
未来结果:10 <= << <<预期2
pre_destroy结束

预期输出:

  post_construct开始
post_construct结束
其他:ton_of_work开始
其他:小睡
其他:醒来:0
其他:小睡
其他:醒来:1
其他:小睡
其他:醒来:2
其他:小睡
pre_destroy started
cancel result:true<<<<<<<实际假
其他:ton_of_work中断<<<<<<实际缺失
其他:ton_of_work返回
未来结果:2 <<<<<<实际10
pre_destroy结束


解决方案

EJB 3.1 only提供合作的异步插话;也就是说,EJB可以检查客户端是否已经调用cancel。即使调用了Future.cancel(true),也没有办法获得一个实际的Thread.interrupt。



有一个开放的EJB规范问题( EJB_SPEC-73 )允许实际线程中断。这是在EJB 3.2专家组中讨论的( 1 ,/ h> , 4 5 6 ),但讨论最终被推迟到下一版本的EJB规范。


What am I doing wrong in this simplest of examples? (Glassfish 4.0-b87 + Eclipse Kepler m6)

Myself.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");
  }
}

Other.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

Expected 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: 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 only provides cooperative async interupts; that is, the EJB can check if the client has called cancel. There is no way to get an actual Thread.interrupt even if Future.cancel(true) is called.

There is an open EJB specification issue (EJB_SPEC-73) to allow actual thread interrupts. This was discussed on the EJB 3.2 expert group (1, 2, 3, 4, 5, 6), but the discussion was eventually deferred to the next version of the EJB specification.

这篇关于无法取消对EJB的异步调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆