在Java中,当我们从具有Future线程的函数返回时会发生什么?

时间:2017-10-02 15:46:56

标签: java multithreading java.util.concurrent concurrent.futures

我想知道当我们等待Future Tasks完成并返回之前会发生什么? 从函数返回后,未来的任务是否仍然完成,或者所有线程都被杀死。 例如:

@AllArgsConstructor
public class IdGenerator() {
    private DBPersister dbPersister;
    public String generateId(){
        String id = UUID.randomString();
        Future<Void> persistIdInDB =  dBPersister.persist(id);
        return id;
    }    
}

我想在生成后立即将id返回到下游,并且不想等待将其存储在数据库中。从函数返回是否会杀死函数中创建的所有未来任务?或者我可以放心,dbPersister.persist函数一旦被调用就会被完全执行?如果没有,有什么方法可以在Java中实现相同的目标吗?

2 个答案:

答案 0 :(得分:2)

从方法返回时,您可以确定的是:

  • [value] - max[value] over (intersect([Type],[ID],previous([Date]))) 将被调用
  • 当前主题不会阻止,因为您未dBPersister.persist(id);
  • 调用get

只有通过查看Future<Void>的实现,以及由于环境变量(例如数据库关闭等)是否成功持久性,才能发现持久性方面具体发生的事情。

答案 1 :(得分:1)

Future只是一个界面。由个人实现如何提供方法cancel()get()isCancelled()done()

例如,您可以编写一个返回Future的方法,该方法只是同步完成工作:

    public Future<Void> print(String x) {
        System.out.println(message);
        return new Future<Void>() {
            @Override
            public boolean cancel(boolean mayInterruptIfRunning) {
                return false;
            }

            @Override
            public boolean isCancelled() {
                return false;
            }

            @Override
            public boolean isDone() {
                return true;
            }

            @Override
            public Void get() throws InterruptedException, ExecutionException {
                return null;
            }

            @Override
            public Void get(long timeout, TimeUnit unit)
                    throws InterruptedException, ExecutionException, TimeoutException {
                return null;
            }
        };
    }

同样,你可以编写自己的实现,直到调用get()才能完成工作! (这在多线程上下文中不是很好的代码,但它说明了这一点):

 public Future<Void> foo(String x) {
        return new Future<Void>() {

            private boolean done = false;

            @Override
            public boolean cancel(boolean mayInterruptIfRunning) {
                return false;
            }

            @Override
            public boolean isCancelled() {
                return false;
            }

            @Override
            public boolean isDone() {
                return done;
            }

            @Override
            public Void get() throws InterruptedException, ExecutionException {
                System.out.println(message);
                done = true;
                return null;
            }

            @Override
            public Void get(long timeout, TimeUnit unit)
                    throws InterruptedException, ExecutionException, TimeoutException {
                return get();
            }
        };
    }

DBPersister来自第三方库,或者您自己的某个库。我们无法猜测它是如何实施的Future

返回Future s的内容示例的主流是ExecutorService。典型的ExecutorService将继续运行,直到调用其shutdown(),然后它将停止接受新任务,处理其队列中的内容,然后终止。在最后一个线程完成之前,JVM不会停止。

然而,Runtime.exit()有可能突然杀死一切。避免叫它;或者,如果你无法避免,请了解关闭钩子。