资讯专栏INFORMATION COLUMN

线程系列三、synchronized 关键字

xzavier / 617人阅读

摘要:是如何加锁的从字节码层面看生了个字节码命令代表进入代表退出从层面看问题一的锁信息存放在哪里的锁信息存放在对象头中。对象头中包含个部分示例数据存放对象的字段内容中包含了锁的标记位。线程不会被挂起。重量级锁线程会被挂起,会被切换出去。

1、synchronized 关键字的锁对象是谁?

①当synchronized 关键字加在实例方法上,那么锁对象是当前类实例

示例代码

synchronized void a() {
    try {
        Thread.sleep(3000L);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("a");
}

synchronized void b() {
    System.out.println("b");
}

public static void main(String[] args) {
    ThreadTest test = new ThreadTest();
    new Thread(() -> {
        test.b();
    }).start();

    new Thread(() -> {
        test.a();
    }).start();
}

②、当synchronized 关键字加在静态方法上,那么锁对象是当前类

示例代码

static synchronized void a() {
     System.out.println("aaaa");
    try {
        Thread.sleep(3000L);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("a");
}

static synchronized void b() {
    System.out.println("b");
}

public static void main(String[] args) {
    ThreadTest test = new ThreadTest();
    ThreadTest test1 = new ThreadTest();
    new Thread(() -> {
        ThreadTest.a();
    }).start();

    new Thread(() -> {
        ThreadTest.b();
    }).start();
}

2、synchronized 关键字可重入吗?

synchronized 是可重入的!

示例代码

synchronized void a() {
    System.out.println("aaaa");
    b();
    try {
        Thread.sleep(3000L);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("a");
}

synchronized void b() {
    System.out.println("b");
}

public static void main(String[] args) {
    ThreadTest test = new ThreadTest();
    test.a();
}

a方法中调用b方法。因为当前的锁对象是类的实例,调用a方法时,可以立马调用b方法,说明sychronized是可重入的。

3、synchronized是如何加锁的?

①从字节码层面看

Jvm 生了2个字节码命令

monitorenter代表进入

monitorexit代表退出

②从jvm层面看

问题一:synchronized的锁信息存放在哪里?

synchronized 的锁信息存放在对象头中。

对象头中包含2个部分

1、MarkDown

2、示例数据(存放对象的字段内容)

MarkDown 中包含了锁的标记位。

其中锁有偏向锁,轻量级锁,重量级锁。

3者的使用场景如下:1个线程进入临界区,多个线程交替进入临界区,多个线程同时进入临界区

偏向锁
只有1个线程进入临界区,线程获取锁之后,不会释放锁,再次进入的时候无需再次加锁

轻量级锁
多个线程交替进入临界区,以自旋的方式进行忙循环。线程不会被挂起。也就是线程不会被切换出去。

重量级锁
线程会被挂起,会被切换出去。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/76679.html

相关文章

  • Java多线程学习()volatile键字

    摘要:三关键字能保证原子性吗并发编程艺术这本书上说保证但是在自增操作非原子操作上不保证,多线程编程核心艺术这本书说不保证。多线程访问关键字不会发生阻塞,而关键字可能会发生阻塞关键字能保证数据的可见性,但不能保证数据的原子性。 系列文章传送门: Java多线程学习(一)Java多线程入门 Java多线程学习(二)synchronized关键字(1) java多线程学习(二)synchroniz...

    tain335 评论0 收藏0
  • Java多线程学习(二)synchronized键字(1)

    摘要:转载请备注地址多线程学习二将分为两篇文章介绍同步方法另一篇介绍同步语句块。如果两个线程同时操作对象中的实例变量,则会出现非线程安全,解决办法就是在方法前加上关键字即可。 转载请备注地址: https://blog.csdn.net/qq_3433... Java多线程学习(二)将分为两篇文章介绍synchronized同步方法另一篇介绍synchronized同步语句块。系列文章传送门...

    xuxueli 评论0 收藏0
  • Java多线程学习(二)synchronized键字(2)

    摘要:关键字加到非静态方法上持有的是对象锁。线程和线程持有的锁不一样,所以和运行同步,但是和运行不同步。所以尽量不要使用而使用参考多线程编程核心技术并发编程的艺术如果你觉得博主的文章不错,欢迎转发点赞。 系列文章传送门: Java多线程学习(一)Java多线程入门 Java多线程学习(二)synchronized关键字(1) java多线程学习(二)synchronized关键字(2) J...

    Batkid 评论0 收藏0
  • Java多线程学习(四)等待/通知(wait/notify)机制

    摘要:运行可运行状态的线程获得了时间片,执行程序代码。阻塞的情况分三种一等待阻塞运行的线程执行方法,会把该线程放入等待队列中。死亡线程方法执行结束,或者因异常退出了方法,则该线程结束生命周期。死亡的线程不可再次复生。 系列文章传送门: Java多线程学习(一)Java多线程入门 Java多线程学习(二)synchronized关键字(1) java多线程学习(二)synchronized关键...

    PiscesYE 评论0 收藏0
  • Java 并发编程系列之带你了解多线程

    摘要:的内置锁是一种互斥锁,意味着最多只有一个线程能持有这种锁。使用方式如下使用显示锁之前,解决多线程共享对象访问的机制只有和。后面会陆续的补充并发编程系列的文章。 早期的计算机不包含操作系统,它们从头到尾执行一个程序,这个程序可以访问计算机中的所有资源。在这种情况下,每次都只能运行一个程序,对于昂贵的计算机资源来说是一种严重的浪费。 操作系统出现后,计算机可以运行多个程序,不同的程序在单独...

    Elle 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<