Java同步方法锁定对象还是方法?

标签 java multithreading thread-safety locking 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()

最佳答案

如果您将方法声明为 已同步(就像您通过键入 public synchronized void addA() 所做的那样),您将在整体上同步> 对象,因此从同一个对象访问不同变量的两个线程无论如何都会相互阻塞。

如果你想一次只同步一个变量,这样两个线程在访问不同变量时不会互相阻塞,你可以在 synchronized () block 中分别同步它们。如果 ab 是您将使用的对象引用:

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

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

但是因为它们是原始的,所以你不能这样做。

我建议你改用 AtomicInteger:

import java.util.concurrent.atomic.AtomicInteger;

class X {

    AtomicInteger a;
    AtomicInteger b;

    public void addA(){
        a.incrementAndGet();
    }

    public void addB(){ 
        b.incrementAndGet();
    }
}

关于Java同步方法锁定对象还是方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3047564/

相关文章:

c# - 线程池是否在应用程序域之间共享?

c# - 同时访问2个线程上的对象

c# - 为什么这种双重检查锁定是正确的? (。网)

.net - 最大化线程数以充分利用所有可用资源而不影响整体性能

c++ - 在多核 MacOSX 上,以下 c++ 代码是线程安全的吗?

java - Java 中的委托(delegate)与回调

Java 和我应该使用哪个 Stun 库?

java - gwtp 应用程序中生成源的 Maven 处理器插件顺序

java - 将文件列表与对象列表进行比较以删除文件

javascript - 在后台线程中执行Javascript代码