我不清楚
Java在进入实例同步java方法时获取对象级锁,在进入静态同步java方法时获取类级锁。
当它说对象级锁和类级锁时,意味着什么?
例如,:
public class Counter{
private static int count = 0;
private int count2 = 0;
public static synchronized int getCount(){
return count;
}
public synchronized setCount(int count2){
this.count2 = count2;
}
} getCount()在这里将锁定Counter.class对象,而setCount()将锁定当前对象(此)。这个指的是什么?这是否意味着当getCount()被调用时,另一个线程不能访问setCount(),因为整个类都被锁定了?
发布于 2012-08-22 14:36:27
当它说对象级锁和类级锁时,意味着什么?
当您锁定一个static方法时,您将锁定Class对象本身,并且每个ClassLoader都有其中一个。在你的例子中,
public static synchronized int getCount(){这是对Counter.class对象的锁定,与以下相同:
public static int getCount() {
synchronized (Counter.class) {
}如果您正在锁定一个不是static的方法,那么您将锁定拥有该方法的对象的实例。在你的例子中:
public synchronized void setCount(int count){这与锁定特定的Counter实例相同,相当于:
public void setCount(int count){
synchronized (this) {
...因此,如果有两个Counter对象,counter1和counter2,而一个线程同时调用counter1.getCount(),另一个线程同时调用counter2.getCount(),那么它们都会锁定同一个Class对象,其中一个会阻塞另一个。
但是,如果这两个线程正在调用counter1.setCount(...)和counter2.setCount(),那么它们将锁定不同的对象-- counter1和counter2。他们不会互相阻拦。
如前所述,在setter和getter上存在不对称的形式是非常糟糕的,而且不寻常的是,要么是static。
这是否意味着当getCount()被调用时,另一个线程不能访问setCount(),因为整个类都被锁定了?
不是的。如果调用getCount(),则Counter.class被锁定,而当setCount(...)被称为counter1或counter2时,则被锁定。只有当同一个对象被另一个线程锁定时,锁才会阻塞线程。仅仅因为Counter.class上有一个锁,并不意味着存在某种uber类锁。阻止另一个线程的唯一时间是如果它在Counter.class上太锁。
我会花点时间读一下Sun的作品。
发布于 2012-08-21 22:37:51
在Java中,类的每个类和每个实例都具有它们的内部锁。这些是在进入和退出synchronized方法时获得和释放的锁。
与往常一样,this引用调用setCount()的实例,因为每个实例都有自己的内部锁,所以只要对类的另一个实例调用setCount(),对setCount()的第二次调用就不会被阻塞,但是对正在进行另一个setCount()调用的实例调用setCount()的尝试将被阻止。
类锁和实例锁是不同的,因此getCount()和setCount()永远不会互相干扰。
发布于 2012-08-21 22:40:58
static成员与类关联,而不是与特定实例关联。因此,static成员上的同步在整个类上有效地同步,因为静态是类成员。
实例成员与类的实例相关联(例如,复杂的this锁),因此如果您在成员字段(非静态)或this上同步,那么您就有一个与实例对象相关联的锁。
在您的示例中,getCount在类的intrinsik锁上同步。实际上你正在做的是:
public setCount(int count){
synchronized(this){
this.count = count;
}
}如果您这样做了,那么您将在类级别进行同步:
static Object count = new Object();
synchronized(count){
}https://stackoverflow.com/questions/12064041
复制相似问题