Java线程暂停一段时间

huangapple go评论76阅读模式
英文:

Java thread stopping for a while

问题

我有以下问题。我有一个部署在Tomcat服务器上的Springboot Java应用程序。我正在使用SimpleAsyncTaskExecutor和@Scheduled来每隔10分钟运行一些任务。但有时执行会突然停止,一段时间后才继续,有时是2分钟,有时是10分钟,有时根本不会继续执行。

我尝试过增加Tomcat的最大内存,但没有效果。我确信这不是未捕获的异常,所以我认为可能是线程饥饿,但我该如何解决这个问题?

英文:

I've the following problem. I've a Springboot Java app deployed in a tomcat server. I'm using SimpleAsyncTaskExecutor and @Scheduled to run some tasks every 10 min. But sometimes the execution just stops, and continues after a while, sometimes 2 minutes, sometimes 10, and sometimes it just doesn't continue the execution.

I've tried increasing the tomcat max memory, but this didn't work. Im sure it's not an uncaught exception, so I think it may be thread starvation, but how can I solve this?

答案1

得分: 1

Yes, 我们能在执行冻结时获取线程转储吗?它们显示了什么?为了调试这类问题,我过去会获取一系列间隔5到10秒的5个线程转储,并使用类似https://fastthread.io/的线程转储分析工具进行分析。

英文:

Were you able to take thread dumps when the execution is frozen? What do they show? To debug issues like this, I used to take a sequence of 5 thread dumps 5 to 10 seconds apart and analyze them with some thread dump analyzer tool like https://fastthread.io/

答案2

得分: 0

如果这是线程饥饿的问题,那么你可以在方法声明中使用关键字synchronized,或者在关键代码处创建一个synchronized{}代码块。此外,你可以使用Lock,并使用lock()unlock()方法提供的Lock

注意:如果你使用Lock,将关键代码放在try{} finally块中,以确保始终释放内部锁。

lock.lock();      //使用锁
try {
    //执行关键代码部分。
} finally {
    lock.unlock();  //释放锁,以便其他线程可以使用它。
}
英文:

If it's thread starvation issue then you can use the keyword synchronizedin your method declarations or create a synchronized{} block of code wherever there is critical code . Also you can use a Lock and use .lock() and .unlock() methods provided with Lock.

Note-if you are using Lock put your critical code in a try{} finally block so you always release the intrinsic lock.

lock.lock();      //using lock 
        try {
            //execute critical section of the code.
        } finally {
            lock.unlock();//release the lock so other thread can use it.
        }
 

答案3

得分: 0

以下是翻译好的部分:

两件事可能正在发生:

  1. 您的线程正在等待监视器
  2. 垃圾收集正在执行停止-世界收集。

您可以使用 -xloggc 开关向您的应用程序添加垃圾收集日志。这样,您将对您的堆有更清晰的了解。

您还可以在线程被锁定之前、之后和同时使用 jstack 或 kill -3 来获取堆栈跟踪。您可以将此操作分别运行并将输出保存到文件中。

您还可以连接 jconsole 到您的应用程序并检查您的堆和线程。

英文:

Two things could be happening:

  1. your threads are waiting for monitor
  2. GC is doing stop-the-world collection.

You could add GC log to your application using -xloggc switch. That way you will have a better picture of your heap.

You can also take stack trace using jstack or kill -3 before , after and while the threads are locked up. You can run this separately and output to a file.

You could also connect jconsole to your application and examine your heap and threads

huangapple
  • 本文由 发表于 2020年8月1日 05:18:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/63199205.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定