简体   繁体   English

java中的多线程调试

[英]Multithreaded debugging in java

I have a program that runs about 50 threads . 我有一个运行大约50 threads的程序。 I employ a producer consumer design pattern to communicate data between the threads. 我使用生产者消费者设计模式来在线程之间传递数据。 After the program has been running for a while, sometimes it freezes due to one of the BlockingQueue's I use to distribute data between the threads becomes full, and therefore the main distribution part of the program blocks when it tries to add data to this BlockingQueue. 程序运行一段时间之后,有时会因为我用来在线程之间分配数据的BlockingQueue之一冻结,因此程序的主要分发部分在尝试向此BlockingQueue添加数据时会阻塞。 In other words, one of the threads stops for some reason and then the blockingQueue it uses to receive data becomes full. 换句话说,其中一个线程由于某种原因停止,然后用于接收数据的blockingQueue变满。

How do I go about debugging this in an efficient manner? 如何以有效的方式进行调试? I have tried surrounding the content in all run() methods with catch(Exception e) , but nothing is ever thrown. 我尝试用catch(Exception e)包围所有run()方法中的内容,但是没有抛出任何东西。 I develop in Java/IntelliJ . 我用Java/IntelliJ开发。

Any thoughts, ideas or general guidelines? 任何想法,想法或一般准则?

"Debug it" by using a logger. 使用记录器“调试它”。 I like SLF4J . 我喜欢SLF4J

Set up log.debug statements before and after each critical operation. 在每个关键操作之前和之后设置log.debug语句。 Use log.entering and log.exiting calls at the start and end of each method. 在每个方法的开头和结尾使用log.enteringlog.exiting调用。

While you are 'debugging' you'll run your application with the logger set to a very low level (FINEST) then run your application and watch the logging statements to learn when it fails and what the state is when it fails. 当您“调试”时,您将运行应用程序并将记录器设置为非常低级别(FINEST),然后运行您的应用程序并观察日志记录语句以了解它何时失败以及失败时的状态。

Since you're worried about a threading issue, make sure your log format includes the thread name or number. 由于您担心线程问题,请确保您的日志格式包含线程名称或编号。

general guidelines? 一般准则?

I don't know if this applies to your situation, but a very important guideline is to never have locks being taken in different orders. 我不知道这是否适用于您的情况,但一个非常重要的指导原则是永远不会以不同的顺序进行锁定。

An example: 一个例子:

Thread 1: 线程1:

ResourceA.lock();
ResourceB.lock();
...
ResourceB.unlock();
ResourceA.unlock();

Thread 2: 线程2:

ResourceB.lock();
ResourceA.lock();
...
ResourceA.unlock();
ResourceB.unlock();

Now if thread 1 is interrupted when it already owns ResourceA but not yet ResourceB , and thread 2 is allowed to run, thread 2 will take ResourceB . 现在,如果线程1时,它已经拥有被中断ResourceA但尚未ResourceB和线程2允许运行,线程2将ResourceB Then thread 1 owns ResourceA and waits for ResourceB , and thread 2 owns ResourceB and waits for ResourceA , so you have a deadlock. 然后线程1拥有ResourceA并等待ResourceB ,线程2拥有ResourceB并等待ResourceA ,因此您有一个死锁。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM