Java对象锁和类锁全面解析

一、对象锁与类锁

        1. 首先应该了解jvm内存模型才能更深入理解:

          (1)栈区:主要存储的是局部变量值和对象引用,常量池的引用,每个线程私有

         (2)堆区:主要存储的是对象实例、数组,所有线程共享此区域;

         (3)方法区:主要存储静态变量、静态常量、静态方法、类信息,所有线程共享此区域;

         (4)程序计数器:当前程序执行指令的地址,每个线程私有

       2.什么是类锁,什么是对象锁他们在并发环境下的问题;

           类锁:锁是加持在类上的,用synchronized static 或者synchronized(class)使用的锁都是类锁,因为class和静态方法在系统中只会产生一份,所以在单系统环境中使用类锁是线程安全的;

public class TestLock {

public synchronized static void methodName1() {
System.out.println("类锁方式一");
}

public void methodName2() {
synchronized (TestLock.class) {
System.out.println("类锁方式二");
}
}
}

        对象锁:synchronized 修饰非静态的方法synchronized(this)都是使用的对象锁,一个系统可以有多个对象实例,所以使用对象锁不是线程安全的,除非保证一个系统该类型的对象只会创建一个(通常使用单例模式)才能保证线程安全;

//案例:单例模式保证对象锁安全

public class TestLock {

private static TestLock testLock=null;

//私有化构造函数不允许new来产生对象
private TestLock() {
}

//保证一个系统只会创建一个对象实例
public synchronized static TestLock GetInstance() {
if (testLock == null) {
synchronized (TestLock.class) {
if (testLock == null) {
testLock = new TestLock();
}
}
}
return testLock;
}

public synchronized void methodName1() {
System.out.println("对象锁方式一");
}

public void methodName2() {
synchronized (TestLock.this) {
System.out.println("对象锁方式二");
}
}
}

参考:https://zhuanlan.zhihu.com/p/31537595

          https://blog.csdn.net/u013142781/article/details/51697672

二、synchronized关键字在继承中用法

public class Widget {
    public synchronized void doSomething(){
        System.out.println("Father:   "+this);
        //...
    }
}


class LoggingWidget extends Widget{
    public synchronized void doSomething(){
        System.out.println("Son:   "+this);
        System.out.println(toString()+":calling doSomething");
        super.doSomething();
    }
}

class Test{
    public static void main(String[] args) {
        LoggingWidget w1=new LoggingWidget();
        w1.doSomething();
    }

输出为:

Son:   并发.LoggingWidget@659e0bfd
并发.LoggingWidget@659e0bfd:calling doSomething
Father:   并发.LoggingWidget@659e0bfd

        super.doSomething()语句的输出为:     并发.LoggingWidget@659e0bfd

       说明了:1.synchronized修饰非static方法为对象锁

                     2.synchronized方法没有继承性

                    3.当在子类中super.父类synchronized方法时,任然是有锁的,只是锁为子类对象 (2.3有点矛盾,我的理解是因为锁对象变了,所以不具有继承性)

                    4.子类继承父类,重写父类的synchronized方法,两个synchronized方法的锁对象是同一个锁,为同一个锁且还是子类对象作为锁。

参考:https://blog.csdn.net/liuyancainiao/article/details/81707025

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值