Java中synchronized方法锁是线程粒度的吗

在Java中,我们经常使用synchronized关键字来实现线程同步,保证多个线程安全地访问共享资源。synchronized关键字可以修饰方法,也可以修饰代码块。那么,synchronized方法锁是线程粒度的吗?这是一个很常见的问题,让我们来深入探讨一下。

synchronized方法锁的粒度

在Java中,synchronized方法锁是以对象为粒度的,而不是以线程为粒度。当一个线程访问一个对象的synchronized方法时,它会获得该对象的锁,其他线程将无法访问该对象的其他synchronized方法,直到当前线程释放了该对象的锁。

这意味着当一个对象中有多个synchronized方法时,同一时刻只有一个线程可以执行这些方法,即使这些方法是不同的方法。这也就是说,synchronized方法锁是对象级别的,而不是方法级别的。

代码示例

让我们通过一个简单的示例来说明这个问题。假设有一个包含两个synchronized方法的类:

public class SynchronizedExample {

    public synchronized void method1() {
        System.out.println("method1 start");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("method1 end");
    }

    public synchronized void method2() {
        System.out.println("method2 start");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("method2 end");
    }
}

在这个示例中,SynchronizedExample类包含了两个synchronized方法method1和method2。当一个线程访问其中一个方法时,另一个方法将被锁住,无法被其他线程访问。

现在,我们创建两个线程并分别调用这两个方法:

public class Main {

    public static void main(String[] args) {
        SynchronizedExample example = new SynchronizedExample();

        Thread thread1 = new Thread(() -> {
            example.method1();
        });

        Thread thread2 = new Thread(() -> {
            example.method2();
        });

        thread1.start();
        thread2.start();
    }
}

当我们运行这段代码时,可以看到输出结果类似于:

method1 start
method1 end
method2 start
method2 end

这是因为在这个示例中,两个线程分别调用了method1和method2方法,但是由于这两个方法都是synchronized方法,所以同一时刻只能有一个线程执行其中一个方法,另一个方法将被阻塞。

总结

综上所述,Java中的synchronized方法锁是以对象为粒度的,而不是以线程为粒度。当一个线程获得了一个对象的锁后,其他线程无法同时访问该对象的其他synchronized方法,即使这些方法是不同的方法。

因此,在使用synchronized方法时,需要注意锁的粒度,避免出现不必要的阻塞,提高程序的并发性能。

希望通过本文的介绍,能帮助大家更好地理解Java中synchronized方法锁的粒度问题。如果您有任何疑问或建议,欢迎留言讨论。感谢阅读!