【问题标题】:Detect thread state when using @Async and @Scheduled in Spring在 Spring 中使用 @Async 和 @Scheduled 时检测线程状态
【发布时间】:2017-04-18 12:42:46
【问题描述】:

我正在尝试在 Spring 中实现以下要求。

我有两个正在运行的@Async 线程,我们称它们为t_At_B

t_A 使用 @Scheduled 注释设置,它需要每 30 分钟运行一次(当前设置为 5 秒)。 t_B 应该持续运行,除非 t_A 在此时启动并开始其工作 t_B 将在 x 秒内休眠并重新采样 t_A 状态,一次 t_A 工作done t_B 将继续其工作,直到 t_A 再次启动。

目前我被困在两个主要点:

  1. 我不知道如何访问线程池执行器来检查线程状态

  2. 使用@Scheduled 时,线程似乎永远不会完成,它似乎只是在注释中设置的固定时间休眠。

有什么想法吗?

【问题讨论】:

  • 不是Locks 的选项吗?
  • @FranciscoSpaeth 你能提供使用锁的例子吗?
  • 你有没有想过这个实现的伪代码?
  • @FranciscoSpaeth 并不是真的我发布这个是为了获得一些想法或示例,以便我可以开始
  • t_A 是否应该等到t_B 完成循环迭代?

标签: java spring multithreading spring-boot


【解决方案1】:

由于您的争用程度较低,一个简单的ReentrantLock 应该可以完成这项工作。

首先在t_At_B之间创建一个共享锁:

final ReentrantLock lock = new ReentrantLock();

在能够执行他们的任务之前,t_At_B 必须获得锁,并且锁将强制在给定时间只有一个任务(t_A 或 t_B)能够执行:

t_A:

@Scheduled(...)
public void process() {
    // Acquire the lock, wait forever until the lock owner t_B release the lock
    lock.lock();
    try {
      //do the job
    } finally {
       lock.unlock();
    }
}

t_B:

while (true) {
  // try to acquire the lock, wait 500ms until the lock owner t_A release the lock
  boolean acquired = lock.tryLock(500, TimeUnit.MILLISECONDS);
  if (acquired) {
    try {
      //do the job
    } finally {
      lock.unlock();
    }
  }else{
    // t_A is already running, output a log for example
  }
}

请注意,由于您的争用较低(最多 2 个线程),因此可以使用 synchronized 简化此代码。这实际上取决于您尝试使用锁实现的目标。

【讨论】:

  • 这正是我所需要的,你为我节省了很多时间
猜你喜欢
  • 2013-01-15
  • 2020-06-06
  • 1970-01-01
  • 2018-10-31
  • 2020-06-22
  • 2016-08-21
  • 2015-08-03
  • 2021-07-09
  • 2015-11-05
相关资源
最近更新 更多