Java并行数据库调用

标签 java

我有一个网络应用程序,需要非常快。但为了进行处理,它需要访问多个数据源。因此,我认为进行并行调用以进行优化可能会很有用。

基本上我想并行进行许多不同的数据库调用。您能给我推荐一些简单可靠的方法和技术来实现我的目标吗?如果您能提供一些框架和设计模式,那就太好了。

现在我正在使用Spring。

最佳答案

您可以使用新的Java 8 CompletableFuture 。它允许使用异步现有的同步方法。

假设您有一个格式为 List<DBRequest> listRequest 的请求列表您想要并行运行。您可以通过以下方式创建一个流并异步启动所有请求。

List<CompletableFuture<DBResult>> listFutureResult =
                     listRequest.stream()
                                .map(req -> CompletableFuture.supplyAsync(
                                              () -> dbLaunchRequest(req), executor))
                                .collect(Collectors.toList());    
List<DBResult> listResult = 
                     listFutureResult.stream()
                                     .map(CompletableFuture::join)
                                     .collect(Collectors.toList());

为了有效,您必须编写自己的自定义 Executor

private final Executor executor = 
    Executors.newFixedThreadPool(Math.min(listRequest.size(), 100),
                                 new ThreadFactory(){
               public Thread newThread(Runnable r){
                    Thread t = new Thread(r);
                    t.setDaemon(true);
                    return t;
               }
});

像这样,你可以有足够的线程,但不能太多。将线程标记为守护进程可以让您即使一个线程被阻塞也能完成程序。

您可以在本书的第 11 章 Java 8 in action 中找到有关这些技术的清晰解释。

== Java 7 更新 ==

如果您坚持使用 Java 7,可以使用以下解决方案:

class DBResult{}
class DBRequest implements Callable<DBResult>{
    @Override
    public DBResult call(){return new DBResult();}
}
class AsyncTest{
   public void test(){
     try {
         for(Future<DBResult> futureResult : ((ExecutorService)executor).invokeAll(listRequest)){
             futureResult.get();
         }
     } catch (InterruptedException | ExecutionException ex) {
         Logger.getLogger(SoTest.class.getName()).log(Level.SEVERE, null, ex);
     }
   }
}

所有请求都是异步运行的,然后您按照列表的顺序等待它们完成。

最后,要回答评论中的辅助问题,您不必为每个请求创建线程池。

关于Java并行数据库调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29394918/

相关文章:

java - MimeMessage 和 SMTPMessage Java 的区别

java - 无法获取 org.gradle.api.Project 类型的项目 'VERSION_CODE' 的未知属性 ':app'

java - Java中如何将子类中的方法传递给主类

Java 代理 Burp

java - 不明白为什么字符串值突然变成空?

java - 在android中显示布局1在左边,布局2在右边

java - jackson @JsonGetter和@JsonSetter如何工作

java - 使用 Eclipse-ExtensibleAPI 的 OSGi 测试片段依赖性

java - 在一个 @Singleton-bean 中并行运行不同的 @Schedule-methods

java - 如何让Subclass覆盖Class的内部类?