Quarkus 应用程序的 @Async 等效项是什么?

Rob*_*pek 5 multithreading asynchronous quarkus

在一个类中,我想调用一个方法,但不必等到该方法完成。通常在 Spring 应用程序中我会使用 @Async,但是在 Quarkus 应用程序中该怎么做呢?

下面是一个简单的入门示例。在“StartWork”类中,“Work”开始。(我省略了工作接口,但您可以看到它的实现之一:WorkA)。调用“work.do()”后,startWork() 方法应继续执行,而无需等待 work.do() 完成。

@ApplicationScoped
public class WorkA implements Work {
    public void do() {
        System.out.println("Starting work A.");
        try {
            Thread.sleep(1000l);
            System.out.println("Finished work A.");
        } catch(InterruptedException ex) {
            System.out.println("My work got interrupted.");
        }
    }
}

@ApplicationScoped
public class StartWork {

@Inject
Work work;

    public void startWork() {
        work.do();
        System.out.println("I dont' care when and if the work finished, but it has started.");
    }
}
Run Code Online (Sandbox Code Playgroud)

这是相同的示例,但现在我尝试使用 Mutiny:

@ApplicationScoped
public class WorkA implements Work {
    public void do() {
        Uni.createFrom().voidItem().invoke(Runnable -> {
            System.out.println("Starting work A.");
            try {
                Thread.sleep(1000l);
                System.out.println("Finished work A.");
            } catch(InterruptedException ex) {
                System.out.println("My work got interrupted.");
            }
        }
    });
}

@ApplicationScoped
public class StartWork {

@Inject
Work work;

    public void startWork() {
        work.do();
        System.out.println("I dont' care when and if the work finished, but it has started.");
    }
}
Run Code Online (Sandbox Code Playgroud)

运行此示例时,我没有看到正在打印的行。所以我猜匿名可运行程序没有被调用?

最小可重复产品:https://gitlab.com/rmvanderspek/quarkus-multithreading

Rob*_*pek 9

感谢Turing85找到了答案。

事实证明,Quarkus 与 EventBus 一起用于异步操作。生产者已创建,但工作缓慢,因此在消费者订阅该生产者之前不会被调用。

一个工作示例: https: //gitlab.com/rmvanderspek/quarkus-multithreading

简而言之:

@ApplicationScoped
public class WorkA implements Work {

    @Override
    public void doWork() {
        log.info("Do work");

        Uni.createFrom()
        .item(UUID::randomUUID)
        .emitOn(Infrastructure.getDefaultWorkerPool())
        .subscribe()
        .with(this::worker, Throwable::printStackTrace);
    }

    private Uni<Void> worker(UUID uuid) {
        log.info("Starting work: " + uuid);
        try {
            Thread.sleep((long) Math.random() * 1000);
        } catch (InterruptedException ex) {
            log.info("Could not finish work: " + uuid);
            throw new RuntimeException(ex);
        }
        log.info("Finish work: {}.", uuid);
        return Uni.createFrom().voidItem();
    }
}

@ApplicationScoped
public class StartWork {

    @Inject
    Work work;

    public void startWork() {
        work.do();
        System.out.println("I dont' care when and if the work finished, but it has started.");
    }
}
Run Code Online (Sandbox Code Playgroud)