面试题如下:
在下面的代码示例中,a1和a2获取的锁是同一把么?
//伪代码
class A{
public synchronized void test(){}
}
class B{
public static void main(String[] args){
A a1 = new A();
A a2 = new A();
a1.test();
a2.test();
}
}
答:不是同一把
解析:这道题考的是面试者对于对象锁及类锁的了解。从名字可以知道对象锁是针对对象实例的,具有唯一性。而类锁是针对某个类,面对类的所有对象实例。
synchronized关键字对于两种锁的表现形式如下:
1.对象锁
class A{
final Object lock = new Object();
public synchronized void test(){}
public void test1(){
synchronized(this){}
//或者锁住非静态成员变量
synchronized(lock){}
}
}
2.类锁(全局锁)
class A{
static final Object lock = new Object();
public static synchronized void test(){}
public void test1(){
synchronized(A.class){}
//或者锁住静态成员变量
synchronized(lock){}
}
}
个人理解(从其他方面):
对于对象锁来说,通过new来创建新的对象之后,对象中的Monitor对象都是一个新的对象。在每次通过synchronized关键字获取锁时,需要针对monitor对象进行monitorenter和monitorexit操作。既然操作的monitor对象都不是同一个,那么说明获取的也不是同一把锁。