代码之家  ›  专栏  ›  技术社区  ›  ErVeY

有没有办法知道EJB异步进程的进度?

  •  4
  • ErVeY  · 技术社区  · 15 年前

    我试图从EJB异步进程中获取进度百分比。这可能吗?

    有人知道我怎么做吗?

    3 回复  |  直到 9 年前
        1
  •  2
  •   Community Mohan Dere    5 年前

    要了解异步进程的进度总是很棘手的,尤其是当您不知道它们是否已经实际启动时。

    hashmap 使用当前进程。您可能需要查看并发Hashmap( http://download-llnw.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ConcurrentHashMap.html )

    然后另一个查找函数将只获取唯一的id,并将进度返回给客户机。

    然后,当它完成后,您返回了错误消息或success,然后从hashmap中删除它,客户机得到了信息,并且该信息不会更改,因此没有必要保留它。

    在您的界面中创建一个新函数

    String progressDone(String id);
    

    然后您将同步地引用它,因为它只是出去然后马上回来,所以它可以查找 id 散列表 并返回完成百分比或错误消息。

    但是,这意味着您的实际worker函数需要经常将信息放入hashmap中,以确定其位置,这就是我建议使用并发hashmap的原因,这样您就不必担心并发写入以及锁定问题。

        2
  •  1
  •   Dmitry    8 年前

    异步作业本身:

    @Stateless
    public class AsyncRunner implements AsyncRunnerLocal {
        @Asynchronous
        public Future<ResultObject> doWorkAsynchronous(WorkContext context) {
            context.setRunning(true);
            for (int i = 0; i < 100; i++) {
                //Do the next iteration of your work here
                context.setProgress(i);
            }
            context.setRunning(false);
            return new AsyncResult(new ResultObject());
        }
    }
    

    共享上下文对象。这里最重要的是volatile关键字。字段值将本地缓存在每个线程中,如果没有它,则主线程中的进度将不可见:

    public class WorkContext {
        //volatile is important!
        private volatile Integer progress = 0;
        private volatile boolean running = false;
        //getters and setters are omitted
    }
    

    public class ProgressChecker {
        @EJB
        private AsyncRunnerLocal asyncRunner;
    
        private WorkContext context;
        private Future<ResultObject> future;
    
        public void startJob() {
            this.context = new WorkContext();
            future = asyncRunner.doWorkAsynchronous(this.context);
            //the job is running now
            while (!future.isDone()) {
                System.out.println("Progress: " + this.context.getProgress());
                Thread.sleep(1000); //try catch is omitted
            }
        }
    }
    
        3
  •  0
  •   Michael Konietzka    15 年前

    在EJB3.1中 @Asynchronous 方法调用可以返回 java.util.concurrent.Future ,此接口提供信息 boolean isCancelled() boolean isDone() ,但没有执行是否开始的信息。从我的观点来看,如果进程以标准方式通过EJB容器开始执行,就无法获得信息。

    推荐文章