首页 > 其他分享 >synchronized关键字与Lock锁原理

synchronized关键字与Lock锁原理

时间:2023-06-14 20:55:18浏览次数:50  
标签:抢占 synchronized Lock 阻塞 关键字 线程 java public

1.synchronized

synchronized关键字是JVM提供的内置锁,是通过Monitor两种来实现的,分别是当其作用在类上和方法上时。
类上:

  • 测试代码
public class Test {

    public void test() {
        synchronized (this) {
            System.out.println(1);
        }
    }

}
  • 测试类的反编译结果,执行javap -v Test.class
.....
public void test();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=3, args_size=1
         0: aload_0
         1: dup
         2: astore_1
         3: monitorenter
         4: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         7: iconst_1
         8: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
        11: aload_1
        12: monitorexit
        13: goto          21
        16: astore_2
        17: aload_1
        line 10: 4
        line 11: 11
        line 12: 21
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      22     0  this

  • 分析
    从上面的反编译class文件可以看出,synchronized关键字作用在类上时,其是通过monitor锁来实现的,通过monitorenter指令来表示资源已被锁定,monitorexit指令来表示资源已被释放。
    另外,资源在被锁定的时候mointor会将monitor的计数设置为1,由于synchronized是可重入锁,所以如果是同一个线程再次持有该锁时,则会将monitor的计数加1。如果是不同的线程则会阻塞。而资源在被释放的时候则会将计数进行减1,当计数为0时,则证明该资源已被释放,可以被其他线程获取。

方法上:

  • 测试代码
public class Test {

    public synchronized void test() {
        System.out.println(1);
    }

}
  • 测试类的反编译结果,执行javap -v Test.class
......
 public synchronized void test();
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_SYNCHRONIZED
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: iconst_1
         4: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
         7: return
      LineNumberTable:
        line 9: 0
        line 10: 7
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       8     0  this

  • 分析
    通过上面的反编译结果可以看出当synchronized关键字作用在方法上时其是通过标志ACC_SYNCHRONIZED来进行表示的,当方法上有该标志时,则说明当前方法是由synchronized关键字进行修饰的,需要进行相应的加锁操作,是隐式的。

2.Lock

lock是java中的一个类。其主要实现是通过五个方法lock(),lockInterruptibly(),trylock(),
trylock(time:long, unit:TimeUnit),unlock()

  • lock()
    阻塞模式抢占锁,如果当前线程抢占锁成功,那么其继续向下执行程序的业务逻辑,否则,当前线程会阻塞,直到持有锁的线程释放锁后再继续抢占锁。
  • lockInterruptibly()
    可中断模式抢占锁的方法。当前线程在抢占锁的过程中,能够响应中断信号,从而能够中断当前线程。
  • trylock()
    非阻塞模式下抢占锁的方法。抢占锁时,线程不会阻塞,而会立即返回抢占锁的结果。
  • trylock(time:long, unit:TimeUnit)
    在trylock()的基础上,加了抢占锁的时间限制
  • unlock()
    释放锁

关于lock的源码解析,可以看AQS与CAS分析这篇博客。

3.总结

类别 synchronized lock
存在层次 Java的关键字,属于jvm层面 java中的一个类
是否需要手动释放 不需要手动释放,jvm会自动帮忙释放 需要在final块中手动进行释放
锁的获取 只有阻塞模式抢占锁一种,一个线程获取之后,另一个线程需要阻塞 有多种模式,可阻塞,可非阻塞
锁状态 无法判断 可以判断
锁类型 可重入,不可中断,非公平 可重入,可中断,可公平也可非公平
性能 少量同步 大量同步

标签:抢占,synchronized,Lock,阻塞,关键字,线程,java,public
From: https://www.cnblogs.com/mcj123/p/17469708.html

相关文章

  • 关于xfs文件系统-在操作系统中遇到两个uuid一样的-挂载报错-wrong fs type, bad optio
    当操作系统中,出现了两个uuid一样的文件系统(笔者这里是xfs),那么默认就只能挂载成功一个[root@qq-5201351~]#blkid|grepxfs|grep1ea9e784-0692-403c-bed1-bf34a5a86a57/dev/nvme1n1:UUID="1ea9e784-0692-403c-bed1-bf34a5a86a57"BLOCK_SIZE="512"TYPE="xfs"/dev/nvme2......
  • Java并发之 Lock 锁
    一、Lock接口1Lock简介&地位&作用锁是一种工具,用于控制对共享资源的访问Lock和synchronized是最常见的两个锁,他们都能够达到线程安全的目录,但是使用和功能上又有较大的不同Lock接口最常见的实现类就是ReentrantLock通常情况下Lock只允许一个线程访问共享资源,特殊情况也允......
  • 【python】关键字global
    关键字global1.局部变量和全局变量重名:定义了一个全局变量site,接着,我们定义了一个函数func,同时,在函数func里面,我们首先打印变量site的值,接着再次给变量site赋值。最后,调用函数func,此时程序报错,理论上我们在func函数里面第一次打印使用的应该是全局变量site,但实际上程......
  • OnceCell和OnceLock的介绍
    OnceCell和OnceLock都是Rust标准库中用于实现懒加载的数据结构,它们能够确保一个变量只被初始化一次。OnceCell是用于单线程环境下的懒加载数据结构。它可以用来存储某个值,并在需要时进行初始化,但是只能在单线程环境下使用。在多线程环境下,使用OnceCell会导致数据竞争问题......
  • 关于mkfs.xfs创建xfs文件系统指定block-size为512字节时报错-Minimum block size for
    今天笔者看到mkfs.xfs命令的帮助文档手册时,有如下一段内容可以通过-bsize=value的方式指定block的大小,默认值是4096bytes,最小为512,最大为65536Thedefaultvalueis4096bytes(4KiB),  theminimumis512,andthemaximumis65536(64KiB).于是笔者就尝试,创建x......
  • macOS系统adb logcat grep 过滤多个关键字
    macOS系统adblogcatgrep过滤多个关键字: 1、过滤单个关键字:adblogcat|grep"error" 2、过滤多个关键字:adblogcat|grep-e"error"-e"warning"-e"fatal" 把日志保存到本地:adblogcat|grep-e"error"-e"warning"......
  • synchronized和volatile区别
    synchronized和volatile区别个人理解JMM:JavaMemoryModel(Java内存模型),根据并发过程中如何处理、可见性、原子性和有序性这三个特性而建立的模型。可见性:JMM提供了volatile变量定义、final、synchronized块来保证可见性。原子性:个人理解是如果执行,就执行完,synchronized块来保证......
  • NMI watchdog :BUG:softlockup 解决方案
    问题现象:解决方案:解决办法:设置为30s覆盖到配置文件中echo30>/proc/sys/kernel/watchdog_thresh查看tail-1/proc/sys/kernel/watchdog_thresh30临时生效sysctl-wkernel.watchdog_thresh=30常见原因:1>服务器电源供电不足,导致CPU电压不稳导致CPU死锁2>vcpus超过物理cpu实......
  • 按关键字API接口搜索天眼查企业数据
    一、如果你想要查找某一个企业的基本信息或是对行业中的企业进行筛选,那么使用API接口搜索天眼查企业数据会非常方便。首先,你需要获取天眼查API的access_token,这可以通过注册账号获取。一旦你获得了access_token,你就可以开始使用API接口了。在使用API接口之前,你需要明确搜索关键......
  • c关键字认识
    下表列出了C中的保留字。这些保留字不能作为常量名、变量名或其他标识符名称。关键字说明auto声明自动变量break跳出当前循环case开关语句分支char声明字符型变量或函数返回值类型const定义常量,如果一个变量被const修饰,那么它的值就不能再被改变cont......