Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在EJB3中不使用线程处理超时_Java_Multithreading_Timeout_Ejb 3.0 - Fatal编程技术网

Java 在EJB3中不使用线程处理超时

Java 在EJB3中不使用线程处理超时,java,multithreading,timeout,ejb-3.0,Java,Multithreading,Timeout,Ejb 3.0,我有以下情况。我的工作是: 可能在给定的时间后超时,如果发生,则需要抛出异常 如果未超时,将返回一个结果 如果此作业返回结果,则必须尽快返回,因为性能是一个非常重要的问题。因此,异步解决方案已不在讨论之列,通过敲打自然地捆绑系统也不是一种选择 最后,系统必须符合EJB标准,因此不能选择使用普通线程的AFAIK,因为这是严格禁止的 我们当前的解决方案使用一个线程,该线程在存在一定时间后会抛出异常,而不会被外部进程中断,但由于这显然违反了EJB标准,因此我们尝试用其他方法来解决它 有什么想法吗

我有以下情况。我的工作是:

  • 可能在给定的时间后超时,如果发生,则需要抛出异常
  • 如果未超时,将返回一个结果
  • 如果此作业返回结果,则必须尽快返回,因为性能是一个非常重要的问题。因此,异步解决方案已不在讨论之列,通过敲打自然地捆绑系统也不是一种选择
  • 最后,系统必须符合EJB标准,因此不能选择使用普通线程的AFAIK,因为这是严格禁止的
我们当前的解决方案使用一个线程,该线程在存在一定时间后会抛出异常,而不会被外部进程中断,但由于这显然违反了EJB标准,因此我们尝试用其他方法来解决它

有什么想法吗

编辑以添加:当然,超时的作业也需要删除(或中断)

编辑以添加2:
这个问题似乎没有任何解决方案,因为按照纯EJB3标准检测死锁似乎几乎是不可能的。由于Enno Shioji下面的评论反映了这一点,我将他的建议设置为正确答案。

您可以使用commonj WorkManager创建线程。标准中内置了一些实现,正如他们提出的那样,但您也可以找到其他AppServer的实现

基本上,WorkManager允许您在容器内创建托管线程,就像在常规Java中使用执行器一样。您唯一的其他选择是使用MDB,但这将是一个“更重”的解决方案

因为我不知道你的实际平台,你必须自己用你的平台谷歌commonj 8-)

这是一个


注意:这不是一个实际的标准,但它广泛适用于不同的平台,应该很好地满足您的需要。

对于EJB,有一个“容器管理事务”的概念。通过在bean或特定方法上指定@TransactionaAttribute,容器将在调用方法时创建事务。如果代码的执行时间超过事务阈值,容器将抛出异常。如果调用在事务阈值下完成,它将像往常一样返回。您可以捕获调用代码中的异常并进行适当的处理


有关容器管理的事务的更多信息,请查看:和

使用Bean管理的事务,可以使用UserTransaction接口指定特定事务的超时

修改指定的超时值 与已启动的事务关联 由具有begin的当前线程执行 方法

  • 事务将在指定秒后超时&可能无法进一步传播。如果异常不是隐式抛出的,则可以根据结果显式抛出它
  • 将在指定时间内成功完成后返回结果
  • 可以将它与无状态会话bean一起使用,因此可能不会出现性能问题
  • 它的EJB标准,因此这将不是实现的问题
只要稍加修改,它在给定场景中应该可以正常工作

编辑:还可以使用特定于服务器的属性来管理事务超时

JBoss:可以在类或方法级别应用注释
@TransactionTimeout(100)

Weblogic:在Weblogic-ejb-jar.xml中指定参数

<transaction-descriptor>
     <trans-timeout-seconds>100</trans-timeout-seconds> 
</transaction-descriptor>

100
GlassFish:在sunejbjar.xml中使用可选的
cmt timeout in seconds
元素。比如:

<transaction-descriptor>
     <trans-timeout-seconds>100</trans-timeout-seconds> 
</transaction-descriptor>
@Stateless
public class TimedBean {

  @Resource
  private TimerService timerService;

  static private AtomicInteger counter = new AtomicInteger(0);
  static private Map<Integer, AtomicBoolean> canIRunStore = new ...;

  public void doSomething() {
    Integer myId = counter.getAndIncrement();
    AtomicBoolean canIRun = new AtomicBoolean(true);
    canIRunStore.put(myId, canIRun);

    timerService.createTimer(1000, 0, myId);

    while (canIRun.get() /* && some other condition */) {
      // do my work ... untill timeout ... 
    }
  }

  @Timeout
  @PermitAll
  public void timeout(Timer timer) {
    Integer expiredId = (Integer) timer.getInfo();
    AtomicBoolean canHeRun = canIRunStore.get(expiredId);
    canIRunStore.remove(expiredId);
    canHeRun.set(false);
  }
}
@无状态
公共类TimedBean{
@资源
私人TimerService TimerService;
静态私有AtomicInteger计数器=新的AtomicInteger(0);
静态私有映射canIRunStore=new。。。;
公共无效剂量测定法(){
整数myId=counter.getAndIncrement();
AtomicBoolean canIRun=新的AtomicBoolean(真);
canIRunStore.put(myId,canIRun);
timerService.createTimer(1000,0,myId);
while(canIRun.get()/*&&其他一些条件*/){
//做我的工作…直到超时。。。
}
}
@超时
@佩尔米塔尔
公共无效超时(计时器){
整数expiredId=(整数)timer.getInfo();
AtomicBoolean canHeRun=canIRunStore.get(expiredId);
canIRunStore.remove(expiredId);
canHeRun.set(假);
}
}

这更像是要求澄清,但它太长,无法作为评论

我不确定您现在是如何做的,因为从您编写的内容来看,仅仅使用请求处理线程似乎是一种方式。像这样:

//Some webservice method (synchronous)
public Result process(Blah blah){
    try{
        return getResult(TimeUnit.SECONDS, 10);
    }catch(InterruptedException e){
        //No result within 10 seconds!
        throw new ServiceUnavailableException("blah");
    }
}
我不知道你为什么要创建线程。如果由于
getResult
方法根本没有超时而被迫使用线程,则会出现线程泄漏。如果在超长时间之后超时,因此你想“快捷”地回复用户,那将是我考虑使用线程的唯一情况,就像我想象你如何使用它一样。这可能会导致线程在负载下堆积,我会努力避免这种情况

也许你可以发布一些代码,让我们知道你为什么要在你的服务中创建

还有,你的客户端界面是什么?听起来像是一个同步Web服务还是什么


在这种情况下,如果我是你,我会使用一个
HashedWheelTimer
作为一个单身。。。这个机制应该非常适合您的需求()。然而,不幸的是,这似乎与EJB规范中对线程的禁止和对单例的禁止相冲突。事实上,如果您这样做的话,确实没有问题。例如,见。我们还在EJB应用程序中使用了单例模式。它使用JBoss。然而,如果这不是一个可行的选择,那么我可能会