1.说明

  Java中的锁按等级分可以分为对象锁、方法锁、类锁。

  对象锁和方法锁其实是同一个东西

  java的对象锁和类锁:java的对象锁和类锁在锁的概念上基本上和内置锁是一致的,但是,两个锁实际是有很大的区别的,对象锁是用于对象实例方法,或者一个对象实例上的,类锁是用于类的静态方法或者一个类的class对象上的。我们知道,类的对象实例可以有很多个,但是每个类只有一个class对象,所以不同对象实例的对象锁是互不干扰的,但是每个类只有一个类锁。但是有一点必须注意的是,其实类锁只是一个概念上的东西,并不是真实存在的,它只是用来帮助我们理解锁定实例方法和静态方法的区别的

2示例

2.1示例1

package com.jinsenianhua.common.utils.contractPoi;

/**
 * @Classname Thread1
 * @Description TODO
 * @Date 2021/7/26 0026 下午 3:54
 * @Created by jcc
 */
public class Test0 {

    private int num = 0;
    public synchronized void printNum(String arg){

        if (arg.equals("a")){
            num = 100;
            System.out.println("num value is "+ num);
            try {
                new Thread().sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }else {
            num = 200;
            System.out.println("num value is "+ num);
        }
        System.out.println("tag = " + arg + " num = " + num);
    }

    public static void main(String[] args) {
        final Test0 t1 = new Test0();

        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                t1.printNum("a");
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                t1.printNum("b");
            }
        });

        thread1.start();
        thread2.start();
    }

}

  打印结果:

    num value is 100
    tag = a num = 100
    num value is 200
    tag = b num = 200

    上面这个锁在普通方法上,是方法锁。可以看到,锁生效了。这个锁是对象级别的,我创建了一个对象,他们的锁对象是不一样了,所以锁生效。

2.2示例2

package com.jinsenianhua.common.utils.contractPoi;

/**
 * @Classname Thread1
 * @Description TODO
 * @Date 2021/7/26 0026 下午 3:54
 * @Created by jcc
 */
public class Test {

    private int num = 0;
    public synchronized void printNum(String arg){

        if (arg.equals("a")){
            num = 100;
            System.out.println("num value is "+ num);
            try {
                new Thread().sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }else {
            num = 200;
            System.out.println("num value is "+ num);
        }
        System.out.println("tag = " + arg + " num = " + num);
    }

    public static void main(String[] args) {
        final Test t1 = new Test();
        final Test t2 = new Test();

        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                t1.printNum("a");
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                t2.printNum("b");
            }
        });

        thread1.start();
        thread2.start();
    }

}

  打印结果:

  num value is 200
  num value is 100
  tag = b num = 200
  tag = a num = 100

  上面这个锁在普通方法上,是方法锁。可以看到,锁是没有生效的。这里和上面的区别是,创建的是两个对象。因为这个锁是对象级别的,我创建了两个对象,他们的锁对象是不一样了,所以锁没有生效。

2.3示例3

package com.jinsenianhua.common.utils.contractPoi;

/**
 * @Classname Test2
 * @Description TODO
 * @Date 2021/7/26 0026 下午 4:02
 * @Created by jcc
 */
public class Test2 {

    private static int num = 0;
    public static synchronized void printNum(String arg){

        if (arg.equals("a")){
            num = 100;
            System.out.println("num value is "+ num);
            try {
                new Thread().sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }else {
            num = 200;
            System.out.println("num value is "+ num);
        }
        System.out.println("tag = " + arg + " num = " + num);
    }

    public static void main(String[] args) {
        final Test2 t1 = new Test2();
        final Test2 t2 = new Test2();

        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                t1.printNum("a");
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                t2.printNum("b");
            }
        });

        thread1.start();
        thread2.start();
    }

}

  打印结果:

    num value is 100
    tag = a num = 100
    num value is 200
    tag = b num = 200

   上面这个锁在静态方法上,是类锁。可以看到,锁生效了。因为这个锁是类级别的,所有对象的锁是同一个,我创建了两个对象,但是他们的锁对象是同一个,所以锁生效。