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



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

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

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

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

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

最新更新