欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

synchronized关键字修饰非静态方法和修饰静态方法有什么区别

程序员文章站 2022-06-24 12:06:56
参考:Java对象锁和类锁全面解析参考:Synchronized同步静态方法和非静态方法总结参考图书:《Java多线程编程核心技术 》 作者:高洪岩很遗憾,我没有能找到synchronized修饰static方法的实际应用,哪怕是在哪个大型开源框架中用到也好。直接上结论:synchronized修饰非静态方法,实际上是对调用该方法的对象加锁,俗称“对象锁”。synchronized修饰静态方法,实际上是对该类对象加锁,俗称“类锁”。关于synchronized 修饰静态方法的情况,我们直....

参考:Java对象锁和类锁全面解析
参考:Synchronized同步静态方法和非静态方法总结
参考图书:《Java多线程编程核心技术 》 作者:高洪岩

很遗憾,我没有能找到synchronized修饰static方法的实际应用,哪怕是在哪个大型开源框架中用到也好。直接上结论:

  • synchronized修饰非静态方法,实际上是对调用该方法的对象加锁,俗称“对象锁”。
  • synchronized修饰静态方法,实际上是对该类对象加锁,俗称“类锁”。

关于synchronized 修饰静态方法的情况,我们直接看代码实例:

public class Run {
    public static void main(String[] args) {
        ThreadA a = new ThreadA();
        a.setName("A");
        a.start();

        ThreadB b = new ThreadB();
        b.setName("B");
        b.start();
    }
}

class Service {
   synchronized public static void printA() {
        try {
            System.out.println("线程名称为:" + Thread.currentThread().getName()
                    + "在" + System.currentTimeMillis() + "进入printA");
            Thread.sleep(3000);
            System.out.println("线程名称为:" + Thread.currentThread().getName()
                    + "在" + System.currentTimeMillis() + "离开printA");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    synchronized public static void printB() {
        System.out.println("线程名称为:" + Thread.currentThread().getName() + "在"
                + System.currentTimeMillis() + "进入printB");
        System.out.println("线程名称为:" + Thread.currentThread().getName() + "在"
                + System.currentTimeMillis() + "离开printB");
    }
}

class ThreadA extends Thread {
    @Override
    public void run() {
        Service.printA();
    }

}


class ThreadB extends Thread {
    @Override
    public void run() {
        Service.printB();
    }
}

运行结果:

线程名称为:A在1466149372909进入printA
线程名称为:A在1466149375920离开printA
线程名称为:B在1466149375920进入printB
线程名称为:B在1466149375920离开printB

两个线程在争夺同一个类锁,因此同步

  • synchronized (class)

对上面Service类代码修改成如下:

class Service {

    public static void printA() {
        synchronized (Service.class) {
            try {
                System.out.println("线程名称为:" + Thread.currentThread().getName()
                        + "在" + System.currentTimeMillis() + "进入printA");
                Thread.sleep(3000);
                System.out.println("线程名称为:" + Thread.currentThread().getName()
                        + "在" + System.currentTimeMillis() + "离开printA");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

    public static void printB() {
        synchronized (Service.class) {
            System.out.println("线程名称为:" + Thread.currentThread().getName()
                    + "在" + System.currentTimeMillis() + "进入printB");
            System.out.println("线程名称为:" + Thread.currentThread().getName()
                    + "在" + System.currentTimeMillis() + "离开printB");
        }
    }
}

运行结果:

线程名称为:A在1466149372909进入printA
线程名称为:A在1466149375920离开printA
线程名称为:B在1466149375920进入printB
线程名称为:B在1466149375920离开printB

两个线程依旧在争夺同一个类锁,因此同步

问题:关键字synchronized修饰static方法,很少见,在哪里用到了?

本文地址:https://blog.csdn.net/zhangjin1120/article/details/110246656

相关标签: java基础