dri*_*tan 12 java multithreading android synchronized
我是java中的多线程新手,我有一个问题,有些人可能会发现微不足道.
我必须调试第三方代码,我需要一些基本信息,知道在哪里寻找问题,因为代码非常大.
运行以下代码时:
public void method()
{
long startTime = System.currentTimeMillis();
synchronized (obj)
{
log( "time:" + System.currentTimeMillis() - startTime + " ms" );
...
}
}
Run Code Online (Sandbox Code Playgroud)
我明白了:
11:13:12 - time: 3816 ms
...
11:14:14 - time: 0 ms
Run Code Online (Sandbox Code Playgroud)
为什么需要这么长时间(3816毫秒)才能获得对象的锁定?我应该在哪里看?例如,我想可能的答案是寻找获取"obj"锁定的代码,例如:
synchronized (obj) { ... }
Run Code Online (Sandbox Code Playgroud)
或者是否可能在没有"synchronized"的对象"obj"上进行任何修改也可以锁定对象?
Mal*_*alt 11
如果获取锁定的线程很长,那是因为其他人正在持有它.
你应该找两件事:
synchronize在同一对象或其他引用上的代码块(称为synchronized语句):
synchronized (obj) {
...
}
Run Code Online (Sandbox Code Playgroud)对象本身内的同步方法.
说obj是类型MyObject,那么你应该寻找这样的方法:
public class MyObject{
public synchronized void myMethod() {
...
}
}
Run Code Online (Sandbox Code Playgroud)
因为它们基本相同
public class MyObject{
public void myMethod() {
synchronized (this) {
...
}
}
}
Run Code Online (Sandbox Code Playgroud)
因此,如果线程正在执行obj.myMethod(),那么想要输入synchronized (obj)块的线程将必须等待,因为它们都锁定在同一个对象上.顺便说一句,这就是我强烈建议永远不要使用synchronized方法语法,并始终锁定私有(或受保护)类成员的原因.
如果另一个线程当前正在这样的块中执行代码,则当前线程将被锁定,直到另一个线程完成.
您可以使用jvisualvm的Threads选项卡或Jstack来获取所有线程的当前执行状态及其持有的锁的快照.如果您使用的是Android,请参阅此答案,了解如何在那里获取线程转储.
| 归档时间: |
|
| 查看次数: |
1524 次 |
| 最近记录: |