我对java中的多线程很陌生,有些人可能会觉得我有些小问题。
我必须调试第三方代码,我需要一些基本信息,以知道在哪里查找问题,因为代码非常大。
当运行以下代码时:
public void method()
{
long startTime = System.currentTimeMillis();
synchronized (obj)
{
log( "time:" + System.currentTimeMillis() - startTime + " ms" );
...
}
}我得到:
11:13:12 - time: 3816 ms
...
11:14:14 - time: 0 ms为什么要花这么长时间(3816 ms)才能得到对象的锁?我该去哪看看?例如,我可以想象一个可能的答案是寻找获取"obj“锁的代码,例如:
synchronized (obj) { ... }或者,没有“同步”的对象"obj“上的任何修改是否也可以锁定对象?
发布于 2015-03-02 17:17:13
如果需要那么长的线程才能获得锁,那是因为其他人正在持有锁。
你应该寻找两件事:
synchronize位于同一对象或对其的其他引用(称为同步语句)上:
同步(obj) {.}obj是MyObject类型的,那么您应该查找这样的方法:
公共类MyObject{公共同步空myMethod() {.}}
因为它们在本质上和
公共类MyObject{公共myMethod() {同步(此){.}}
因此,如果线程正在执行obj.myMethod(),希望进入synchronized (obj)块的线程将不得不等待,因为它们都锁定在同一个对象上。顺便说一下,这就是为什么我强烈建议不要使用同步方法语法,并且总是锁定私有(或受保护的)类成员。如果另一个线程当前正在此块中执行代码,则当前线程将被锁定,直到其他线程完成为止。
您可以使用jvisualvm的线程选项卡或贾斯塔克来快照所有线程的当前执行状态及其所持有的锁。如果您使用的是安卓系统,请参见这关于如何在该系统上获得线程转储的答案。
发布于 2015-03-02 17:14:51
作为jdk一部分的J堆栈实用程序可以帮助实现这一点。-l (long清单)选项将打印由不同线程持有的所有锁。如果您可以在问题中捕捉到您的程序,那么您可以找到另一个线程,该线程持有该锁。要做到这一点,您可以找到线程,查看它正在等待的条件对象,然后搜索该条件对象的堆栈跟踪的其余部分。
这个文章有关于如何查看线程转储的更详细信息。
发布于 2015-03-02 17:10:24
您需要检查以下内容:
https://stackoverflow.com/questions/28815476
复制相似问题