【问题标题】:LazyFutureStream and multiple thread persistenceLazyFutureStream 和多线程持久化
【发布时间】:2015-09-15 12:03:29
【问题描述】:

我正在使用simple-react

LazyFutureStream里面我要持久化实体。

LazyFutureStream.parallel(1,2,3,4,5)
       .map(id -> {
            try {
                SessionFactory sessionFactory = Application.getHibernateBundle()
                                                           .getSessionFactory();
                ManagedSessionContext.bind(sessionFactory.openSession());
                Session session = sessionFactory.getCurrentSession();
                session.beginTransaction();

                Model model = new Model(sessionFactory);
                model.persist(id);
                session.getTransaction().commit();
            }
        });

这是正确的吗?有什么办法可以跳过每个线程的会话工厂创建。

同样在上面我只想分叉而不是加入。可以吗?

【问题讨论】:

  • 不,这是不正确的。您的try 块缺少catchfinally。除此之外,map 操作通常应该 map 从一个项目/值到另一个,因此关联的函数必须返回一个值。如果您只是想消费物品,forEach 可能是您的选择。如果您不想为每个项目创建新的 Session,请将其创建代码移出 lambda 表达式。
  • 如果我将 Session 移出,那么它将被共享一个,这会导致一些关于线程并发的问题
  • 我对 hibernate 的了解还不够多,不能说一下Session 类的线程安全。但万一不是,您总是可以将非线程安全组件的供应商包装到ThreadLocal 中。这样,您可以安全地为每个线程创建一个,但仍会跳过由同一工作线程处理的项目的创建。但也许有人会就Session 的线程安全给出一个明确的答案。同时,您可以尝试在其文档中搜索答案……
  • 您的意思是 threadLocal.set(session) 将使会话对象独占它。类似的所有其他线程,。如果在线程本地设置,将为每个线程复制相同的会话对象

标签: hibernate java-8 cyclops-react


【解决方案1】:

我是 simple-react 的作者,虽然我绝对不是 Hibernate 的 SessionFactory 方面的专家,但这些 Stackoverflow 帖子确实表明跨线程共享它们是安全的。

优化您的信息流

LazyFutureStream.parallel 使用 Common ForkJoinPool(与标准 Java 8 并行流相同)。因此,如果您在应用程序的其他地方使用这些(尤其是 CPU 密集型任务),它们将与您的阻塞 I/O 竞争。

LazyReact StreamBuilder

您可以使用 LazyReact Stream Builder 来设置一个使用自定义线程池的 Stream 构建器(并重用该构建器,JVM 在垃圾收集线程池方面做得不好)。

设置一个带有 10 个线程的线程池的 Stream 构建器,并允许 10 个活动的 Futures -

    LazyReact streamBuilder = new LazyReact(10,10);

创建您的信息流

正如 Holger 建议的那样,您可以使用 forEach(这在 simple-react v0.99.x 及更高版本上很有效,在以前的版本中,peek/run 组合会表现得更好)

   streamBuilder.of(1,2,3,4,5)
                 .forEach(id-> { //do work here });

这将在您的线程池上执行,但会阻塞当前线程,直到工作完成。

对于非阻塞替代方案,您可以使用 run() 和 peek。

   streamBuilder.of(1,2,3,4,5)
                 .peek(id-> { //do work here })
                 .run();

【讨论】:

  • 太棒了!谢谢塔吉尔!
猜你喜欢
  • 1970-01-01
  • 2012-02-08
  • 2021-11-30
  • 2017-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-06
相关资源
最近更新 更多