doFinally 是否在 Reactor 中的同一个线程上执行
Does doFinally execute on the same thread in Reactor
doFinally 是否在同一个线程上执行?下面的代码会阻塞主线程吗?
mono
.map(fileName -> asyncDownloadFile(fileName, folderName))
.doFinally(v -> {
FileUtils.cleanDirectory(folderName); // this method is blocking
});
如果是这样,在 doFinally 的单独线程中执行 cleanDirectory 的最佳方法是什么?
将阻塞调用包装在 Runnable
中,运行 包装在单独的 thread
中:
Runnable task = () -> {FileUtils.cleanDirectory(folderName)};
Mono<Object> cleanDirPromise = Mono.fromRunnable(task);
mono
.map(fileName -> asyncDownloadFile(fileName, folderName))
.doFinally(v -> {
cleanDirPromise.subscribeOn(Schedulers.parallel()).subscribe();
});
注意:这实际上是一个 fire-and-forget 调用,您不会真正关心 cleanDirPromise
的结果。
为此,最好使用 .then()
运算符:
mono
.map(fileName -> asyncDownloadFile(fileName, folderName))
.then()
.flatMap(
Mono.fromRunnable(() -> FileUtils.cleanDirectory(folderName))
.subscribeOn(Schedulers.boundedElastic())
)
...
运算符 then()
保证 cleanDirectory
将在 asyncDownloadFile
之后执行,还允许您构建一个管道并处理错误。
doFinally 是否在同一个线程上执行?下面的代码会阻塞主线程吗?
mono
.map(fileName -> asyncDownloadFile(fileName, folderName))
.doFinally(v -> {
FileUtils.cleanDirectory(folderName); // this method is blocking
});
如果是这样,在 doFinally 的单独线程中执行 cleanDirectory 的最佳方法是什么?
将阻塞调用包装在 Runnable
中,运行 包装在单独的 thread
中:
Runnable task = () -> {FileUtils.cleanDirectory(folderName)};
Mono<Object> cleanDirPromise = Mono.fromRunnable(task);
mono
.map(fileName -> asyncDownloadFile(fileName, folderName))
.doFinally(v -> {
cleanDirPromise.subscribeOn(Schedulers.parallel()).subscribe();
});
注意:这实际上是一个 fire-and-forget 调用,您不会真正关心 cleanDirPromise
的结果。
为此,最好使用 .then()
运算符:
mono
.map(fileName -> asyncDownloadFile(fileName, folderName))
.then()
.flatMap(
Mono.fromRunnable(() -> FileUtils.cleanDirectory(folderName))
.subscribeOn(Schedulers.boundedElastic())
)
...
运算符 then()
保证 cleanDirectory
将在 asyncDownloadFile
之后执行,还允许您构建一个管道并处理错误。