首页 资讯 社群 我的社区 搜索

Java并发之synchronized关键字深度解析(一)

yimo~
2019-12-02 17:56:52

前言

        近期研读路神之绝世武学,徜徉于浩瀚无垠知识之海洋,偶有攫取吉光片羽,惶恐未领略其精髓即隐入岁月深处,遂急忙记录一二,顺备来日吹cow之谈资。本小系列为并发之亲儿子-独臂狂侠synchronized专场。

一、使用场景

        synchronized是java中的一个关键字,用于给对象加锁,保证在单机的并发条件下线程安全。原子性和可见性是它保证线程安全的基础功能。一定要注意它锁的是对象,而且它是一个排他的非公平可重入锁。本文先从使用的场景上来展现其作用。

1、用在普通方法中

常用的格式如下所示:

public static void main(String[] args) {
        Object obj = new Object();
        synchronized (obj) {
            System.out.println("进入锁");
            // 逻辑略去
            System.out.println("退出锁");
        }
    }

其中obj就是我们加锁的对象,同一个对象,同一刻只能由一个线程加锁,即同一个对象的多个同步块,只能顺序执行,无法同时并行执行。

 

2、用在普通方法上

 如下所示:

1 public synchronized void  lockMethod () {
2         System.out.println("进入锁");
3         // 逻辑略去
4         System.out.println("退出锁");
5     }

用在普通方法上时,无需指定锁的对象,这种情况下java默认锁的是当前的实例对象。效果类似于1中,小括号里面是this。

 

3、用在静态方法上

 如下所示:

1 public synchronized static void  lockMethod () {
2         System.out.println("进入锁");
3         // 逻辑略去
4         System.out.println("退出锁");
5     }

这种情况下,synchronized锁的是当前的类对象,此时形成全局锁,即在同一个JVM中,用到此方法的地方都是挨个执行此方法。

 

二、synchronized锁的往事

        大家对JUC包中的lock锁应该都有过了解,它是jdk1.5的时候出现的,刚出来时lock锁的性能全方位碾压synchronized锁。但synchronized作为Java的嫡系子孙,JVM的开发者们肯定要不遗余力地扶持它,所以在jdk1.6中针对synchronized做了很多的优化,使其性能跟lock锁相差无几,亲儿子不愧是亲儿子。在jdk1.6中,synchronized会分不同情况对代码的加锁机制做优化,比如分了三种锁:偏向锁、轻量级锁、自旋锁、重量级锁,设置了锁膨胀策略、锁清除机制,还做了批量重偏向、偏向锁批量撤销等实现方式提高同步块执行效率。后面我会用两节对其原理进行介绍。

三、后记

    何之谓独臂狂侠,盖因发功之时,仅需单臂一刀(引用一次),无需左手加锁右手放锁,而这一刀之功力,便可覆盖周身八丈,浑然天成,劲气运转之时水泼不进,几近无法可破。

用户评论