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修饰/代码块/静态方法,则在各个方法之间也是同步阻塞的。

 

posted @   coding++  阅读(389)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示