获取并发访问的所有线程的堆栈跟踪:

时间:2018-10-10 13:23:48

标签: java debugging concurrentmodification

我们似乎可以同时访问代码中的方法。一种解决方法是同步该方法。但这并不能解决根本原因:首先应该没有这种并发访问。

如何获取所有访问此方法的线程的堆栈跟踪,但是仅在存在并发访问的情况下?

另一种选择是检测同步是否会阻塞-在实际阻塞之前。

2 个答案:

答案 0 :(得分:0)

尝试使用可重入锁以适合此目的。这是示例代码:

private final ReentrantLock lock = new ReentrantLock();

      public void sampleLock() {
        lock.lock();
        try {
          Thread.sleep(5000);
        } catch (InterruptedException e) {
          System.out.println(Thread.currentThread().getName() + "interrupted");
        }
        lock.unlock();
      }

如果任何其他方法想要访问sampleLock()方法,则lock.isLocked()会告诉它是否被其他任何线程使用。 请仔细阅读Oracle文档。 https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html

答案 1 :(得分:0)

在这里有一些选择。

基本代码是

    Lock lock = new ReentrantLock();

    if(!lock.tryLock()) {
        Map<Thread, StackTraceElement[]> threads = Thread.getAllStackTraces();
    }
    try {
        ///your code
    }
    finally {
        lock.unlock();
    }

因此,如果您可以将调试器附加到应用程序,则可以将断点设置为

Map<Thread, StackTraceElement[]> threads = Thread.getAllStackTraces();

行,这将暂停所有线程。然后,您可以在该图中看到所有线程及其堆栈轨迹

如果您无法附加调试器,则只需遍历该映射并获取所有堆栈跟踪即可。

不使用锁的另一种方法是:

private Set<Thread> threads = new HashSet<>();

public void yourMethodInQuestion() {
    threads.add(Thread.currentThread());
    if( threads.size() >= 2 ) {
        //iterate and get all the threads information
    }
    ....
}

我希望有帮助。

迈克尔, Java多线程,并发和性能优化课程

的作者

https://www.udemy.com/java-multithreading-concurrency-performance-optimization/?couponCode=CONCURRENCY