Java++:synchronized用在普通方法上,代码块,静态方法上的区别
普通方法上:
synchronized 在普通方法上为对象锁,不通对象调用时不会阻塞,相同对象调用时为同步阻塞。
示例如下:
public class Task { public synchronized void funA(){ System.out.println("======== start running funA ... ========"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("======== end running funA ... ========"); } public synchronized void funB(){ System.out.println("======== start running funB ... ======== "); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("======== end running funB ... ======== "); } public static void main(String[] args) { // 三个线程分别是同的对象调用funA -- 不会阻塞 for (int i=0; i<3;i++){ new Thread(() -> new Task().funA()).start(); } // 三个线程分别是同的对象调用funB -- 不会阻塞 for (int i=0; i<3;i++){ new Thread(() -> new Task().funB()).start(); } // 三个线程同的对象调用funA -- 同步阻塞 Task task = new Task(); for (int i=0; i<3;i++){ new Thread(() -> task.funA()).start(); } // 三个线程同的对象调用funB -- 同步阻塞 for (int i=0; i<3;i++){ new Thread(() -> task.funB()).start(); } } }
代码块:
synchronized(Task.class)为类锁,则无论是都相同对象调用都为同步阻塞.。
synchronized(this)为对象锁,不通对象调用时不会阻塞,相同对象调用时为同步阻塞。
public class Task { public void funC(){ synchronized(Task.class) { System.out.println("======== start running funC ... ========"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("======== end running funC ... ========"); } } public void funD(){ synchronized(this) { System.out.println("======== start running funD ... ========"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("======== end running funD ... ========"); } } public static void main(String[] args) { // 三个线程分别是同的对象调用funC -- 同步阻塞 for (int i=0; i<3;i++){ new Thread(() -> new Task().funC()).start(); } // 三个线程分别是同的对象调用funD -- 不会阻塞 for (int i=0; i<3;i++){ new Thread(() -> new Task().funD()).start(); } } }
静态方法上:
synchronized在静态方法上为对象锁,无论是否同一对象都为同步阻塞
public class Task { public static synchronized void funE(){ System.out.println("======== start running funE ... ========"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("======== end running funE ... ========"); } public static synchronized void funF(){ System.out.println("======== start running funF ... ======== "); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("======== end running funF ... ======== "); } public static void main(String[] args) { // 三个线程分别是同的对象调用funA -- 同步阻塞 for (int i=0; i<3;i++){ new Thread(() -> new Task().funE()).start(); } // 三个线程分别是同的对象调用funD -- 同步阻塞 Task task = new Task(); for (int i=0; i<3;i++){ new Thread(() -> task.funF()).start(); } } }
总结
对象锁:同一个对象下是同步阻塞的,不同对象之间非阻塞的。
类锁:无论是否为相同对象均为同步阻塞。
同一个类多个方法被synchronized修饰/代码块/静态方法,则在各个方法之间也是同步阻塞的。
分类:
JAVA
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了