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

Getting stack traces for all threads of a concurrent access:

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

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

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

尝试使用可重入锁来满足目的。这是示例代码:

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

这里有几个选项供您选择。

基本代码是

    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