Java中的synchronized方法锁定对象还是方法?

54 浏览
0 Comments

Java中的synchronized方法锁定对象还是方法?

如果在同一个类中有2个同步方法,但是每个方法访问不同的变量,是否可以有2个线程同时访问这2个方法?锁定发生在对象上还是特定于同步方法内部的变量?

例如:

class X {
    private int a;
    private int b;
    public synchronized void addA(){
        a++;
    }
    public synchronized void addB(){
        b++;
    }
}

2个线程可以同时访问X类的同一个实例,执行x.addA()x.addB()吗?

admin 更改状态以发布 2023年5月21日
0
0 Comments

方法声明上的同步机制是这样的:

 public void addA() {
     synchronized (this) {
          a++;
     }
  }

静态方法上的同步机制是这样的:

 ClassA {
     public static void addA() {
          synchronized(ClassA.class) {
              a++;
          }
 }

我认为,如果Java设计者当时知道现在对于同步机制的理解,他们不会加入这个语法糖,因为它往往会导致并发性能的糟糕实现。

0
0 Comments

如果您将方法声明为同步的(通过键入public synchronized void addA()),则对整个对象进行同步,因此访问同一对象的两个线程即使从不同的变量访问也会相互阻塞。\n如果您想一次只同步一个变量,使在访问不同变量时两个线程不会相互阻塞,则必须在synchronized()块中单独同步它们。如果ab是对象引用,则应该使用:

public void addA() {
    synchronized( a ) {
        a++;
    }
}
public void addB() {
    synchronized( b ) {
        b++;
    }
}

但是由于它们是基元类型,因此无法这样做。\n我建议您使用AtomicInteger代替:

import java.util.concurrent.atomic.AtomicInteger;
class X {
    AtomicInteger a;
    AtomicInteger b;
    public void addA(){
        a.incrementAndGet();
    }
    public void addB(){ 
        b.incrementAndGet();
    }
}

0