我是 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 毫秒)来获取对象的锁? 我应该在哪里看?例如,我想一个可能的答案是寻找获取“obj”锁的代码,即 block ,例如:
synchronized (obj) { ... }
或者是否有可能在没有“synchronized”的情况下对对象“obj”的任何修改也可以锁定该对象?
最佳答案
如果一个线程需要很长时间才能获得锁,那是因为其他人当前正在持有它。
你应该寻找两件事:
在同一对象或对它的其他引用上
同步
的代码块(称为synchronized statements):synchronized (obj) { ... }
Synchronized methods在对象本身内。
假设
obj
是MyObject
类型,那么您应该寻找如下方法:public class MyObject{ public synchronized void myMethod() { ... } }
因为它们本质上是一样的
public class MyObject{ public void myMethod() { synchronized (this) { ... } } }
因此,如果线程正在执行
obj.myMethod()
,想要进入synchronized (obj)
block 的线程将不得不等待,因为它们都锁定在同一个对象。顺便说一句,这就是为什么我强烈建议永远不要使用同步方法语法,并且始终锁定私有(private)(或 protected )类成员的原因。
如果另一个线程当前正在执行此类 block 中的代码,则当前线程将被锁定,直到另一个线程完成。
您可以使用 jvisualvm's Threads tab或 Jstack获取所有线程的当前执行状态和它们持有的锁的快照。如果您使用的是 Android,请参阅 this回答如何在那里获取线程转储。
关于java - 为什么这个synchronized block 好像要很久才能拿到锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28815476/