【问题标题】:Configure threads in ParallelStream在 ParallelStream 中配置线程
【发布时间】:2018-05-03 03:35:29
【问题描述】:

我有以下代码

public void addNames(){
   List<String> names = new ArrayList<String>
   names.parallelStream().foreach(name->add(name));
}

private void add(String name){
   SQLSession session = SQLSessionFactory.getSession(config);
   Connection con=Session.openConnection();
   con.insert(name);
   con.commit;
   con.close
}

这里的问题是“name-&gt;add(name)” 将为每个名称执行,我正在为每个名称打开和关闭连接。如果我有数百万条记录,那么这是一个问题。

我无法在“names.parallelStream().foreach(name-&gt;add(name, connection));” 之外打开连接并将其作为参数传递,因为所有线程都会在一个连接对象上阻塞。

所以,我想获取每个线程的连接,我该如何使用 “names.parallelStream().foreach(name-&gt;add(name));”?

我希望每个线程都关注

  1. 获取连接
  2. 插入
  3. 插入
  4. 插入——N个插入
  5. 提交并关闭连接

如果我正在创建和启动一个线程,我可以这样做,我们如何使用 parallelStreams 为每个线程实现这一点?

简而言之,我希望parallelStream中的线程获取每个线程的连接并执行name-&gt;add(name),一旦完成,线程应该提交并关闭连接。这可能吗?

【问题讨论】:

  • 我认为您无法使用 parrelStreams 来实现它。我更喜欢通过批量插入来存储记录,或者如果您想采用上述方法,请考虑使用连接池。

标签: java multithreading parallel-processing java-stream java-threads


【解决方案1】:

我认为您不应该为此强制并行流。如果您以块的形式进行批量插入,您将获得最佳性能。尽管如此,如果你仍然想这样做,你应该有一个连接池,这样每个线程都会获得一个连接并在完成工作后释放它。您的 add 方法如下所示:

private void add(String name){
    Connection con=genCoonection(); //just take a connection from pool
    con.insert(name);
    con.commit;//commit after each record
}

您可以在此处找到有关如何创建和使用连接池的多个示例: How to establish a connection pool in JDBC?

另一种选择是提供自定义ThreadLocal,如here 所述,每个线程将在线程本地打开连接。然后你关闭线程池,连接就会按照here的描述关闭

【讨论】:

  • 我已经有一个连接池。我获取并释放与池的连接。有没有办法避免这样做?至于每条记录,我都应该这样做。我只想按线程执行此操作,以便我可以调用 getConnection 并在最后提交而不是每条记录。在这种方法中,我应该在释放连接时调用 commit
  • @Raj 我想您可以编写一个具有自己连接的池包装器,并在一切结束时调用 commit。您仍然必须在每一步都从池中获取一个对象。
  • 所以我认为,我们没有办法在并行流中设置每个线程的配置
  • 我们可以在任何其他框架中实现这一点,例如 fork join 或 executor services
  • @Raj 您应该停止为每个元素创建一个新会话,并一次插入合理数量的元素(如果不是全部)。并行处理无法弥补您当前方法的根本问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-28
  • 1970-01-01
  • 2021-12-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多