静态方法和非静态方法上加锁的区别

1.静态方法加锁:类锁
Synchronized修饰静态方法,实际上是对该类对象加锁,俗称“类锁”
2.非非静态方法加锁:对象锁
Synchronized修饰非静态方法,实际上是对调用该方法的对象加锁,俗称“对象锁”

public class TestSyn {

    private static int num = 20;

    // 单例模式 静态内部类
    public static TestSyn testSyn = new TestSyn();

    public synchronized void aVoid() {
        for (int i=0;i<10;i++) {
            num--;
            try {
                System.out.println("avoid getNum:" + num);
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public synchronized static void bVoid(){
        for (int i=0;i<10;i++) {
            num--;
            try {
                System.out.println("bVoid getNum:" + num);
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}

测试类:

public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            TestSyn testSyn = new TestSyn();
            testSyn.aVoid();
        });

        Thread thread2 = new Thread(() -> {
            TestSyn.bVoid();
        });

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

结果
在这里插入图片描述
根据执行结果可以得出:静态方法加锁与非静态方法加的锁不是同一个锁
测试类修改成

public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
//            TestSyn testSyn = new TestSyn();
            TestSyn.testSyn.aVoid();
        });

        Thread thread2 = new Thread(() -> {
            TestSyn.bVoid();
        });

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

结果互斥:说明这里静态方法,非静态方法使用了相同的锁。

将方法上的加锁机制做下调整:

public static void bVoid(){
        synchronized(TestSyn.class){
            for (int i=0;i<10;i++) {
                num--;
                try {
                    System.out.println("bVoid getNum:" + num);
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

得出的结果互斥:

总结:

1.对象锁钥匙只能有一把才能互斥,才能保证共享变量的唯一性
2.在静态方法上的锁,和 实例方法上的锁,默认不是同样的,如果同步需要制定两把锁一样。
3.关于同一个类的方法上的锁,来自于调用该方法的对象,如果调用该方法的对象是相同的,那么锁必然相同,否则就不相同。
比如 new A().x() 和 new A().x(),对象不同,锁不同,如果A的单例的,就能互斥。
4.静态方法加锁,能和所有其他静态方法加锁的 进行互斥
5.静态方法加锁,和xx.class 锁效果一样,直接属于类的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值