spring定时任务中的奇怪的Java多线程问题

场景 : 在spring中写一个定时任务,定期从一个DelayQueue对象中获取数据并执行。spring的定时任务的线程采用的是一个大小为8的线程池。

具体代码如下:

public class Timer{
   private final static DelayQueue<String> delayedTasks = new DelayQueue<String>(); 
   
   @Async
   @Scheduled(fixedRate=1000*10)
   public void consume(){
      log.info("开始获取");
      String payment = null;
      try{
         FutureTask<String> future = new FutureTask<String>(new AcquireDelayedTask());
         Thread takeTh = new Thread(future,"my_thread");
         takeTh.start();
         try{
            payment = future.get(1,TimeUnit.SECONDS);
         } catch(TimeoutException e){
            log.info("等待超时,没有获取到");
            return;
         }
      } catch(RuntimeException re){
         return;
      }
   }

   class AcquireDelayedTask implements Callable<String> {
      @Override
      public String call() throws Exception{
         String payment = Timer.delayedTasks.take();
         return payment;
      }
   }
}

问题现象描述
一开始运行时,挺正常。每隔10s执行一次任务,并且代码中的两个log都能够打印出来。(因为测试时,DelayQueue中一直都是空的,所以肯定会打印超时的那条日志。)
就这样正常运行几个小时后,问题出现了:spring定时任务能正常按照10秒的间隔运行,但只会打印"开始获取"这个条日志,另外一条不再打印了。
debug跟踪时发现,代码跑到 takeTh.start(); 这一行就跟踪不下去了(不是多线程无法debug的那种现象),因为 public String call() 这个方法也无法debug,好像线程start了,但一直没有被调度似的。问题出现前,debug都是可以的。

求解,是哪里出问题了?

阅读 2.5k
2 个回答
         } catch(TimeoutException e){
            log.info("等待超时,没有获取到");
            return;
         }
      } catch(RuntimeException re){
         return;
      }

先把异常都好好打出来吧
目测一直在创建线程,达到了某个上限

最佳实践不是加上finally块,在里面执行takeTh.interrupt(),而是处理InterruptedException,

    catch (InterruptedException e) {
        Thread.currentThread().interrupt();  // set interrupt flag
  
    }

参考:中断异常

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题