gpt4 book ai didi

java - google guice 和 spring 的线程问题

转载 作者:行者123 更新时间:2023-11-29 08:49:23 26 4
gpt4 key购买 nike

我需要将现有的 spring 应用程序与自定义的 elasticsearch river 集成,ES rivers 使用 Google Guice 管理它们的依赖关系并在它们自己的线程集中运行。

我创建了一个简单的类,它返回对 spring 上下文的静态引用,并配置了一个从 spring 上下文返回对象的 Guice 模块。为了确保 guice 线程和 spring 线程之间的正确同步,我使用了在上下文完全初始化后释放的 CountDownLatch。这是一些代码

public class GuiceSpringIntegrator implements ApplicationListener<ContextRefreshedEvent> {

private static ApplicationContext context;

private static final CountDownLatch contextLatch = new CountDownLatch(1);

@Override public void onApplicationEvent(ContextRefreshedEvent event) {
try {
// check some stuff in context
} finally {
log.debug("Setting application context as static field of {}", getClass().getSimpleName());
GuiceSpringIntegrator.context = event.getApplicationContext();
log.info("Releasing latch for application context");
contextLatch.countDown();
}
}

public static ApplicationContext getApplicationContext() {
if (null == context) {
log.info("ApplicationContext not yet initialized, wait for it in thread {}", Thread.currentThread().getName());
Uninterruptibles.awaitUninterruptibly(contextLatch); <-- !!! SPRING INITIALIZATION CODE HANGS HERE
log.debug("Returning application context since now context is initialized");
Preconditions.checkState(context != null, "ApplicationContext should have been initialized properly");
}
return context;
}
}

这是使用上面类的guice模块

/**
* Guice module configuration
*/
public class ElasticSearchModule extends AbstractModule {

@Override
protected void configure() {}

@Provides @Singleton TaskScheduler getSchedulerInstance() {
return GuiceSpringIntegrator.getApplicationContext().getBean(TaskScheduler.class);
}
// and so on...
}

但是,当我启动应用程序(尤其是在快速服务器上)时,应用程序偶尔会在上面代码中标记的行处挂起。我仔细检查了导致 #getApplicationContext() 方法调用的每个代码路径,它们(应该)由 guice 调用,因此最终应该释放闩锁,代码应该继续。

  1. 有没有更好的方法来处理这种情况?
  2. 有没有办法检查我是否在 spring 初始化代码中,比如 isEventDispatchThread for swing ?我想使用该代码来跟踪我是否以某种方式从 spring 初始化代码调用 #getApplicationContext
  3. 为什么 #onApplicationEvent 似乎在上下文初始化实际完成之前被调用?
  4. 关于如何调试此问题的任何提示?我在阅读有关在实时服务器上进行线程转储的内容,对吗?

最佳答案

除了第 4 点之外,这并没有真正回答您的问题,但我想编写代码,所以我将其作为答案而不是评论。

我会尝试改变这个:

Uninterruptibles.awaitUninterruptibly(contextLatch); <-- !!! SPRING INITIALIZATION CODE HANGS HERE

为此:

boolean awaitResult = Uninterruptibles.awaitUninterruptibly(contextLatch, 2, TimeUnit.MINUTES);
if(awaitResult) {
throw new IllegalStateException("Unable to load Spring Context");
}

然后您可以在某处捕获该异常并将其堆栈跟踪写入日志;这不会解决您的问题,但它可能会让您更清楚地了解死锁的位置?

关于java - google guice 和 spring 的线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23501967/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com