synchronized锁对象和锁类有区别吗?

1 个回答

  • 张无忌
    做自己,而不是解释自己。
    在 Java 中,`synchronized` 锁对象和锁类是有区别的,具体如下: ### **1. 锁对象(实例锁)** - **锁的范围:** 只锁定当前实例的 `synchronized` 方法或代码块,不同实例之间互不干扰。 - **实现方式:** 使用 `synchronized(this)` 或者在实例方法上直接加 `synchronized` 关键字。 - **特点:** - 如果多个线程访问同一个实例的 `synchronized` 方法或代码块时,线程会互相阻塞。 - 不同实例之间的锁互不影响。 - **适用场景:** 用于保护当前实例的状态。 **代码示例:** ```java class Example { public synchronized void instanceMethod() { System.out.println(Thread.currentThread().getName() + " is executing instance method"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } public void instanceBlock() { synchronized (this) { System.out.println(Thread.currentThread().getName() + " is executing instance block"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } ``` **测试:** ```java public class Main { public static void main(String[] args) { Example example1 = new Example(); Example example2 = new Example(); new Thread(example1::instanceMethod).start(); // 锁 example1 new Thread(example1::instanceBlock).start(); // 也锁 example1 new Thread(example2::instanceMethod).start(); // 锁 example2,不受前两者影响 } } ``` ### **2. 锁类(类锁)** - **锁的范围:** 锁定整个类对象,即所有该类的实例的 `synchronized` 静态方法或 `synchronized` 的类代码块。 - **实现方式:** 使用 `synchronized(ClassName.class)` 或者在静态方法上直接加 `synchronized` 关键字。 - **特点:** - 不管有多少个实例,只要某个线程获得了类锁,其他线程都无法访问该类的 `synchronized` 静态方法或类代码块。 - 实例方法的锁与类锁互不干扰。 - **适用场景:** 用于保护与类相关的共享数据。 **代码示例:** ```java class Example { public static synchronized void staticMethod() { System.out.println(Thread.currentThread().getName() + " is executing static method"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } public void classBlock() { synchronized (Example.class) { System.out.println(Thread.currentThread().getName() + " is executing class block"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } ``` **测试:** ```java public class Main { public static void main(String[] args) { Example example1 = new Example(); Example example2 = new Example(); new Thread(Example::staticMethod).start(); // 类锁 new Thread(example1::classBlock).start(); // 也锁 Example.class new Thread(example2::classBlock).start(); // 同样锁 Example.class } } ``` ### **3. 对比总结** | **特性** | **锁对象(实例锁)** | **锁类(类锁)** | |------------------------|---------------------------------------|------------------------------------| | **锁定对象** | 当前实例 (`this`) | 类对象 (`ClassName.class`) | | **作用范围** | 当前实例的 `synchronized` 代码块或方法 | 所有实例共享的静态 `synchronized` 代码块或方法 | | **互斥影响** | 不同实例之间互不影响 | 所有实例都受类锁影响 | | **常见场景** | 操作实例变量 | 操作类变量或静态资源 | ### **4. 注意点** - **实例锁和类锁互不影响:** 一个线程可以同时持有实例锁和类锁,因为它们锁定的是不同的对象。 - **死锁风险:** 如果线程同时需要实例锁和类锁,设计不当可能导致死锁,需特别小心。
    编辑于 2024-11-25 05:05 •IP属地 美国
    举报
    评论
    收藏