首页 > 其他分享 >万字干货|Synchronized关键字详解

万字干货|Synchronized关键字详解

时间:2022-12-08 09:56:05浏览次数:60  
标签:java Synchronized synchronized 对象 Utf8 干货 线程 详解 monitor

作者:小牛呼噜噜 | https://xiaoniuhululu.com
计算机内功、JAVA底层、面试、职业成长相关资料等更多精彩文章在公众号「小牛呼噜噜

前言

大家好,我是呼噜噜,在之前的文章中https://mp.weixin.qq.com/s/0Ii636KQ9sWwX-OhdlPIYw,我们知道了volatile关键字可以保证可见性、有序性,但无法保证原子性的。今天我们来聊聊synchronized关键字,其可以同时保证三者,实现线程安全。

线程安全

在介绍synchronized关键字之前,我们得强调一下什么是线程安全,所谓线程安全:

当多个线程同时访问一个对象时, 如果不用考虑这些线程在运行时环境下的调度和交替执行, 也不需要进行额外的同步, 或者在调用方进行任何其他的协调操作, 调用这个对象的行为都可以获得正确的结果, 那就称这个对象是线程安全的

什么是synchronized关键字?

在 Java 早期版本中,synchronized 属于 重量级锁,效率低下;不过在 Java 6 之后,Java 官方对从 JVM 层面对 synchronized 较大优化,所以现在的 synchronized 锁效率也优化得非常不错。目前不论是各种开源框架还是 JDK 源码都大量使用了 synchronized 关键字

synchronized实现方式

synchronized的使用其实比较简单,可以用它来修饰实例方法和静态方法,也可以用来修饰代码块。我们需要注意的是synchronized是一个对象锁,也就是它锁的是一个对象。我们无论使用哪一种方法,synchronized都需要有一个锁对象

  1. 修饰实例方法
  2. 修饰静态方法
  3. 修饰代码块

1.修饰实例方法

synchronized修饰实例方法, 在方法上加上synchronized关键字即可。

public class SynchronizedTest1 {
    public synchronized void test() {
        System.out.println("synchronized 修饰 方法");
    }
}

此时,synchronized加锁的对象就是这个方法所在实例的本身,作用于当前实例加锁,进入同步代码前要获得**当前实例的锁 **。

补充一个常见的面试题:构造方法可以用synchronized关键字修饰吗?

不能,也不需要,因为构造方法本身就是线程安全的

2.修饰静态方法

synchronized修饰静态方法的使用与实例方法并无差别,在静态方法上加上synchronized关键字即可

public static synchronized void test(){
       i++;
}

由于静态方法不属于任何一个实例对象,归整个类所有,不依赖于类的特定实例,被类的所有实例共享。给静态方法加synchronized锁,会作用于类的所有对象实例 ,进入同步代码前要获得 当前静态方法所在类的Class对象的锁

有一点我们需要知道:如果一个线程 A 调用一个实例对象的非静态 synchronized 方法,而线程 B 需要调用这个实例对象所属类的静态 synchronized 方法,是允许的,不会发生互斥现象,因为访问静态 synchronized 方法占用的锁是当前类的锁,而访问非静态 synchronized 方法占用的锁是当前实例对象锁

3.修饰代码块

synchronized修饰代码块需要传入一个对象。

public class SynchronizedTest2 {
    public void test() {
        synchronized (this) {
            System.out.println("synchronized 修饰 代码块");
        }
    }
}

此时synchronized加锁对象即为传入的这个对象实例,指定加锁对象,进入同步代码库前要获得给定对象的锁
需要注意的是这里的this

  1. synchronized(object) ,表示进入同步代码库前要获得 给定对象的锁
  2. synchronized(类.class) ,表示进入同步代码前要获得 给定 Class 的锁
  3. 最好不要使用 synchronized(String a) ,因为在 JVM 中,字符串常量池具有缓存功能,如果我们多次加锁,会加锁在同一个对象上

    标签:java,Synchronized,synchronized,对象,Utf8,干货,线程,详解,monitor
    From: https://www.cnblogs.com/xiaoniuhululu/p/16965223.html

相关文章

  • Nginx rewrite 详解
    Nginxrewrite详解本篇主要介绍nginx的rewrite重定向这个功能进行详解介绍,以及介绍它的使用场景1.rewrite基本介绍rewrite是实现URL重写的关键指令,根据reg......
  • 什么叫SSH?原理详解。
    SSH(SecureShell,安全外壳)是一种网络安全协议,通过加密和认证机制实现安全的访问和文件传输等业务。传统远程登录或文件传输方式,例如Telnet、FTP,使用明文传输数据,存在很多的......
  • 【JUC】交换器Exchanger详解
    前言JDK中提供了不少的同步工具,现在分享一个相对比较冷门的同步工具——交换器(Exchanger)。你知道Exchanger的作用是什么吗?实现机制是什么?可以用来做什么呢?Exchanger介绍......
  • ES自定义评分机制:function_score查询详解
    一、function_score介绍主要用于让用户自定义查询相关性得分,实现精细化控制评分的目的。在ES的常规查询中,只有参与了匹配查询的字段才会参与记录的相关性得分score的计算。......
  • session,cookie,token详解
    session,cookie,token详解1.session1.1session的作用是什么session的作用是用于保存每个用户的专用信息;当用户访问时,服务器都会为每个用户分配唯一的SessionID,而且当......
  • Mysql同环比计算详解
    文章目录​​前言​​​​一、什么是同环比​​​​同比​​​​环比​​​​对比​​​​二、同环比计算SQL​​​​1.数据准备​​​​2.年环比和年同比​​​​3.月环比......
  • Mysql加锁流程详解
    目录​​前言​​​​一、锁的内存结构​​​​二、加锁流程​​​​1、加锁的基本流程​​​​2、根据主键加锁​​​​3、根据二级索引加锁​​​​4、根据非索引字段查询......
  • Mysql中锁类型详解
    文章目录​​前言​​​​一、锁的分类​​​​二、锁的特性​​​​1、共享锁和独占锁​​​​2、意向锁​​​​3、标准记录锁RecordLocks​​​​4、间隙锁GapLocks​......
  • mybatis-plus分页查询详解
    文章目录​​一、官方文档​​​​二、内置的分页方法​​​​1、内置方法​​​​2、selectPage单元测试​​​​3、PaginationInnerInterceptor分页插件配置​​​​三、......
  • Mybatis-Plus主键生成策略详解
    文章目录​​前言​​​​一、官网​​​​二、主键注解@TableId说明​​​​1、源码​​​​2、作用​​​​3、使用​​​​三、主键生成策略-IdType枚举说明​​​​1、......