在 Java 中,当我们 return 来自正在进行的 Future 线程的函数时会发生什么?
In Java, what happens when we return from a function with Future threads in progress?
我想知道当我们不等待 Future Tasks 完成并 return 之前会发生什么?
未来的任务是否仍然完成,或者一旦我 return 从函数中杀死所有线程。
例如:
@AllArgsConstructor
public class IdGenerator() {
private DBPersister dbPersister;
public String generateId(){
String id = UUID.randomString();
Future<Void> persistIdInDB = dBPersister.persist(id);
return id;
}
}
我想 return ID 生成后立即发送到下游,不想等待将其存储在数据库中。 return 从函数中调用是否会终止函数中创建的所有未来任务?还是我可以放心,函数dbPersister.persist一旦调用就会完全执行?如果没有,我有什么办法可以在 Java 中实现相同的目标吗?
从您的方法返回时,您可以确定的是:
dBPersister.persist(id);
将被调用
- 当前线程不会阻塞,因为您没有在
Future<Void>
上调用 get
持久化具体会发生什么只能通过查看dBPersister.persist(id);
的实现来发现,以及持久化是否由于环境变量(例如数据库宕机等)而成功
Future
只是一个接口。这取决于各个实现如何提供方法 cancel()
、get()
、isCancelled()
和 done()
.
例如,您可以编写一个 returns 一个 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
.
returns Future
的一个主流例子是 ExecutorService
。一个典型的 ExecutorService
将保持 运行 直到有东西调用它的 shutdown()
,然后它将停止接受新任务,处理其队列中的内容,然后终止。在最后一个线程完成之前,JVM 不会停止。
然而,Runtime.exit()
有可能突然杀死一切。避免调用它;或者,如果您无法避免,请了解关闭挂钩。
我想知道当我们不等待 Future Tasks 完成并 return 之前会发生什么? 未来的任务是否仍然完成,或者一旦我 return 从函数中杀死所有线程。 例如:
@AllArgsConstructor
public class IdGenerator() {
private DBPersister dbPersister;
public String generateId(){
String id = UUID.randomString();
Future<Void> persistIdInDB = dBPersister.persist(id);
return id;
}
}
我想 return ID 生成后立即发送到下游,不想等待将其存储在数据库中。 return 从函数中调用是否会终止函数中创建的所有未来任务?还是我可以放心,函数dbPersister.persist一旦调用就会完全执行?如果没有,我有什么办法可以在 Java 中实现相同的目标吗?
从您的方法返回时,您可以确定的是:
dBPersister.persist(id);
将被调用- 当前线程不会阻塞,因为您没有在
Future<Void>
上调用
get
持久化具体会发生什么只能通过查看dBPersister.persist(id);
的实现来发现,以及持久化是否由于环境变量(例如数据库宕机等)而成功
Future
只是一个接口。这取决于各个实现如何提供方法 cancel()
、get()
、isCancelled()
和 done()
.
例如,您可以编写一个 returns 一个 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
.
returns Future
的一个主流例子是 ExecutorService
。一个典型的 ExecutorService
将保持 运行 直到有东西调用它的 shutdown()
,然后它将停止接受新任务,处理其队列中的内容,然后终止。在最后一个线程完成之前,JVM 不会停止。
然而,Runtime.exit()
有可能突然杀死一切。避免调用它;或者,如果您无法避免,请了解关闭挂钩。