Java锁机制 & Syncronize锁优化

1.什么是锁?
可以参考,美团技术团队《不可不说的Java“锁”事》
在这里插入图片描述

多个线程在竞争一个资源的时候,需要锁机制进行确保资源的使用权。当一个线程占有资源时,其他线程需要阻塞等待(如上图所示)

  1. Java是怎样实现锁机制的?
    在这里插入图片描述

线程共享的区域为:堆 + 方法区
(1)Java堆:所有线程共享的一块内存区域,此内存区域最主要的目的是:存放对象实例,几乎所有对象实例都是在这里分配内存。
(2)方法区:与Java堆一样,是各个线程共享的内存区域,他用于存储被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

针对线程共享的数据(堆中的对象)多个线程在修改同个对象的时候就会产生并发问题。

问题1:你们知道的Java锁机制哪些方法呢?(这个问题某凯不应该不会吧?)

  1. Synchronized锁以及 Synchronized优化锁升级
    先看一段代码
public class A {
    private Integer a;

    public Integer getA() {
        return a;
    }

    public void setA(String name, Integer a) {
        synchronized (this) {
                this.a = a;
            }
        }
}

对这个代码进行编译后得到字节码:

在这里插入图片描述

JDK1.6对Synchronized升级后,Java对象中,每个对象都会有一把锁,这把锁存在Java的"对象头"中

Java对象的组成结构(对象头 + 实例数据 + 填充字节):

在这里插入图片描述

其中对象中的锁存在MarkWord中,所以我们最主要看对象头的MarkWord的数据结构(非结构性):

  1. 32位机器的对象头MarkWord

在这里插入图片描述

  1. 64位机器上对象头MarkWord各个bit的含义
    在这里插入图片描述

(1)无锁 阶段(锁标记位位 01,是否偏向锁:0)
无锁是指没有对资源进行锁定,所有的线程都能访问并修改同一个资源,但同时只有一个线程能修改成功。
无锁的特点是修改操作会在循环内进行,线程会不断的尝试修改共享资源。如果没有冲突就修改成功并退出,否则就会继续循环尝试。如果有多个线程修改同一个值,必定会有一个线程能修改成功,而其他修改失败的线程会不断重试直到修改成功。

代码如下:

public class NoLock {

    private static Object o = new Object();
    public static void main(String[] args) {
        System.out.println(ClassLayout.parseInstance(o).toPrintable());
        System.out.println("hashcode = " + o.hashCode());
        System.out.println(ClassLayout.parseInstance(o).toPrintable());
    }
}

打印结果如下:(可以看到无锁的时候调用hashcode方法后,hashcode是存在markword中的)
PS:此处打印的markword数据是小端模式存储和打印的。 冷知识:为什么对象的分代年龄最大只能调到15?

在这里插入图片描述

(2)偏向锁(锁标记位位 01,是否偏向锁:1)
代码如下:

private static Object o;

public static void main(String[] args) throws InterruptedException {
    Thread.sleep(5000);
    o = new Object();
    lock();
    System.out.println(ClassLayout.parseInstance(o).toPrintable());
}

private static void lock() {
    synchronized (o) {
        System.out.println(ClassLayout.parseInstance(o).toPrintable());
    }
}

单条线程在占有该对象时,锁会偏爱这个线程,此时markword会记录占有的线程ID

(3)轻量级锁(锁标记位位 10)

在这里插入图片描述

(3)重量级锁(锁标记位位 00)

重量级锁
升级为重量级锁时,锁标志的状态值变为“10”,此时Mark Word中存储的是指向重量级锁的指针,此时等待锁的线程都会进入阻塞状态。Java会调用操作系统的 mutex 指令(重量级),此时会涉及到操

弊端:有时候同步代码块执行的时间会远小于线程切换的时间。

锁升级过程:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值