我们似乎可以同时访问代码中的方法。一种解决方法是同步该方法。但这并不能解决根本原因:首先应该没有这种并发访问。
如何获取所有访问此方法的线程的堆栈跟踪,但是仅在存在并发访问的情况下?
另一种选择是检测同步是否会阻塞-在实际阻塞之前。
答案 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多线程,并发和性能优化课程
的作者