synchronized锁静态方法和普通方法区别?
1 个回答
我一路种下蘑菇,只为让你知道回家的路。比比东`synchronized` 锁静态方法和普通方法最大的区别在于锁的对象不同: ### 1. 锁普通方法(实例方法) - **锁住的是调用该方法的**实例对象。 - **效果:** 对同一个实例对象调用的多个普通`synchronized`方法,会互相阻塞;不同实例对象则不会互相阻塞。 ```java public synchronized void instanceMethod() { // 锁住的是当前对象(this) } ``` - 等价于: ```java public void instanceMethod() { synchronized(this) { // ... } } ``` ### 2. 锁静态方法 - **锁住的是该类的 Class 对象**(即`ClassName.class`)。 - **效果:** 只要是该类的静态`synchronized`方法,不论调用多少个实例(甚至无需实例),都会被同一个锁限制访问。 ```java public static synchronized void staticMethod() { // 锁住的是当前类的Class对象(ClassName.class) } ``` - 等价于: ```java public static void staticMethod() { synchronized(ClassName.class) { // ... } } ``` ### 3. 总结对比 | 锁类型 | 锁的对象 | 作用范围 | 相互影响情况 | |---------------------|----------------------|---------------------------------|-----------------------------------| | 普通 synchronized 方法 | 当前实例(this) | 同一实例内的所有普通同步方法 | 同一实例内互斥,不同实例不互斥 | | 静态 synchronized 方法 | 当前类的 Class 对象 | 类级别,影响所有实例及类本身 | 所有实例和类级别方法互斥 | ### 4. 举个例子说明区别: ```java class Demo { public synchronized void instanceMethod() { System.out.println("实例方法 - " + Thread.currentThread().getName()); try { Thread.sleep(1000); } catch (InterruptedException e) {} } public static synchronized void staticMethod() { System.out.println("静态方法 - " + Thread.currentThread().getName()); try { Thread.sleep(1000); } catch (InterruptedException e) {} } } ``` - 如果两个线程调用**同一个实例对象**的`instanceMethod`,它们会互相等待; - 如果两个线程分别调用两个不同实例的`instanceMethod`,则它们不会互相影响; - 如果两个线程调用的是静态方法`staticMethod`,无论用几个实例或不使用实例,都会互相阻塞。 ### 5. 实践中的使用建议: - **实例方法同步**适合对象级别的共享数据操作。 - **静态方法同步**适合类级别共享数据(静态变量等)操作。 实际开发时,应根据锁的粒度和共享资源的类型,来选择合适的锁对象,避免出现性能瓶颈或锁竞争过于严重的情况。发布于 2025-02-28 18:36 •IP属地 内蒙古举报评论收藏
公众号进入网站体验更佳

