在Java中,当我们从一个函数返回并且未来的线程正在进行时会发生什么?

在Java中,当我们从一个函数返回并且未来的线程正在进行时会发生什么?,java,multithreading,java.util.concurrent,concurrent.futures,Java,Multithreading,Java.util.concurrent,Concurrent.futures,我想知道,当我们不等待未来的任务完成并返回之前会发生什么? 将来的任务是否仍然完成,或者一旦我从函数返回,所有线程是否都被终止。 例如: @allargsconstuctor 公共类IdGenerator(){ 私有DBPersister DBPersister; 公共字符串生成器ID(){ 字符串id=UUID.randomString(); Future persistiddb=dBPersister.persist(id); 返回id; } } 我希望在生成id后立即将其返回给下

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

@allargsconstuctor
公共类IdGenerator(){
私有DBPersister DBPersister;
公共字符串生成器ID(){
字符串id=UUID.randomString();
Future persistiddb=dBPersister.persist(id);
返回id;
}    
}

我希望在生成id后立即将其返回给下游,而不希望等待将其存储在数据库中。从函数返回是否会终止函数中创建的所有未来任务?或者我可以保证函数dbPersister.persist一旦被调用就会被完全执行?如果没有,我有没有办法在Java中实现同样的功能?

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

  • dBPersister.persist(id)将被调用
  • 当前线程不会阻塞,因为您没有在
    Future
    上调用
    get

只有通过查看
dBPersister.persist(id)的实现,才能发现持久性方面的具体情况,以及是否由于环境变量(如数据库关闭等)导致持久化成功。

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;
            }
        };
    }
DBPersister
是来自第三方库的文件,或者是您自己的文件。我们无法猜测它是如何实现未来的

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


然而,
Runtime.exit()
有可能突然杀死一切。避免称呼它;或者,如果您无法避免它,请了解关机挂钩。

它不会终止任务,您可以相对确定地假设它将保留数据。当然,如果您只是“忘记”未来,存储期间的异常将以这种方式列出。这取决于上下文。几周前,在执行Functional测试时,我在JPA/Play2上下文中遇到了类似的情况。generateId的调用方可以在dBPersister完成其作业之前关闭事务。从技术上讲,这是可能的。谢谢。我不关心在坚持中会发生什么,不管它是失败还是通过。您可以假设它是一个连接到DB并编写它的通用代码。我只是想确保persist函数被调用并且没有被阻塞。@harshitmodani然后答案是肯定的。如果未在
未来
上调用
get
等,则自行返回
未来
并不意味着阻止或终止调用。它只是一种机制,将方法的执行与终止后返回的任何内容解耦。
    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;
            }
        };
    }
 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();
            }
        };
    }