无法取消对EJB的异步调用 [英] Cannot Cancel @Asynchronous call to 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屋!