返回顶部
首页 > 资讯 > 精选 >Java同步锁synchronized怎么使用
  • 233
分享到

Java同步锁synchronized怎么使用

2023-07-05 15:07:52 233人浏览 独家记忆
摘要

本文小编为大家详细介绍“Java同步锁synchronized怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java同步锁synchronized怎么使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一

本文小编为大家详细介绍“Java同步synchronized怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java同步锁synchronized怎么使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

    一、并发同步问题

    线程安全是Java并发编程中的重点,而造成线程安全问题的主要原因有两点,一是存在共享数据(也称临界资源),二是存在多条线程共同操作共享数据。因此,当存在多个线程操作共享数据时,需要保证同一时刻有且只有一个线程在操作共享数据,其他线程必须等到该线程处理完数据后再进行,这种方式就叫互斥锁。也就是说当一个共享数据被正在访问的线程加上互斥锁后,在同一个时刻,其他线程只能处于等待的状态,直到当前线程处理完毕释放该锁。在 Java 中,关键字 synchronized可以保证在同一个时刻,只有一个线程可以执行某个方法或者某个代码块(主要是对方法或者代码块中存在共享数据的操作),同时synchronized还有另外一个重要的作用,它可以可保证一个线程的变化(主要是共享数据的变化)被其他线程所看到(保证可见性,完全可以替代Volatile功能)。

    二、锁的简介


    synchronized是Java的关键字,是一种同步锁。
    Java的内置锁:每个java对象都可以用做一个实现同步的锁,这些锁称为内置锁。线程进入同步代码块或方法的时候会自动获得该锁,在退出同步代码块或方法时会释放该锁。获得内置锁的唯一途径就是进入这个锁的保护的同步代码块或方法。
    Java内置锁是一个互斥锁,这就是意味着最多只有一个线程能够获得该锁,当线程A尝试去获得线程B持有的内置锁时,线程A必须等待或者阻塞,直到线程B释放这个锁。
    Java的对象锁和类锁:java的对象锁和类锁在锁的概念上基本上和内置锁是一致的,但是两个锁实际是有很大的区别的,对象锁是用于对象实例方法,或者一个对象实例上的,类锁是用于类的静态方法或者一个类的class对象上的。
    在Java中,每个对象都有一把锁和两个队列,一个队列用于挂起未获得锁的线程,一个队列用于挂起条件不满足而等待的线程。而synchronized实际上也就是一个加锁和释放锁的集成。JVM负责跟踪对象被加锁的次数。如果一个对象被解锁,其计数变为0。在任务(线程)第一次给对象加锁的时候,计数变为1。每当这个相同的任务(线程)在此对象上获得锁时,计数会递增。只有首先获得锁的任务(线程)才能继续多次获取该对象上的锁。每当任务离开一个synchronized方法,计数递减,当计数为0的时候,锁被完全释放,此时别的任务就可以使用此资源。

    三、synchronized的三种应用方式

    synchronized可以修饰范围的包括:方法级别,代码块级别;而实际加锁的目标包括:对象锁(普通变量,静态变量),类锁。具体分为三种应用方式:

    1.修饰一个实例方法

    被修饰的方法称为实例同步方法,其作用范围是整个方法,锁定的是该方法所属的对象(即调用该方法的对象)。所有需要获得该对象锁的操作都会对该对象加锁(即访问该对象的其他同步实例方法或进入对该对象加锁的代码块)。实例同步方法的代码如下:

    public synchronized void method(){   // 具体代码}

    当一个对象O1在不同的线程中执行这个同步方法时,他们之间会形成互斥,达到同步的效果。但是这个对象所属类的另一对象O2却能够调用这个被加了synchronized关键字的方法。 每个对象实例对应一把锁,线程只有获得对象实例的锁才能执行它的synchronized方法。 如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法。但是该类的其他对象实例的 synchronized方法是不相干扰的。这种机制确保了同一时刻对于每一个对象实例,其所有声明为 synchronized 的成员方法中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为synchronized)。上边的示例代码等同于如下代码:

    public void method(){   synchronized(this){       //具体代码   }}

    其中this指的是调用这个方法的对象,如O1。可见同步方法实质是将synchronized作用于对象引用。只有获得O1对象锁的线程,才能够调用O1的同步方法,而对O2而言,O1对象锁和它互不关联,其他线程调用O2中的相同方法时,并不会产生同步阻塞。程序也可能在这种情形下摆脱同步机制的控制,造成数据混乱。sychronized修饰方法时需要注意以下3点:

    (1)synchronized关键字不能继承。


    虽然可以使用synchronized来定义方法,但synchronized并不属于方法定义的一部分,因此,synchronized关键字不能被继承。如果在父类中的某个方法使用了synchronized关键字,而在子类中覆盖了这个方法,在子类中的这个方法默认情况下并不是同步的,必须显式地在子类为这个方法加上synchronized关键字才可以。当然,还可以在子类方法中调用父类中相应的方法,这样虽然子类中的方法不是同步的,但子类调用了父类的同步方法,因此,子类的方法也就相当于同步了。这两种方式的示例代码如下:
      手动加上synchronized修饰

    class Parent{  public synchronized void method() {}}class Child{  public synchronized void method() {}}  在子类中调用父类同步方法
    class Parent{  public synchronized void method() {}}class Child{  public synchronized void method() {}}

    (2)在定义接口方法时不能使用synchronized关键字。
    (3)构造方法不能使用synchronized关键字,但可以使用synchronized代码块来进行同步。

    2.修饰一个静态方法

    被修饰的方法被称为静态同步方法,其作用的范围是整个静态方法,锁是静态方法所属的类(即Class对象)。所有需要获得该类的任意对象的锁,都会触发同步。静态同步方法的示例如下图:

    Java同步锁synchronized怎么使用

    上述代码中,虽然创建了SynThread类的两个对象,但是该类中的run方法调用的是静态同步方法,所以在运行过程中会同步执行。因此,synchronized作用在静态方法上时,可以防止多个线程同时访问这个类中的静态方法,它对类的所有实例对象都起作用。

    3.修饰一个代码块


    被修饰的代码块称为同步语句块。synchronized的括号中必须传入一个对象(实例对象或类的Class对象)作为锁。其作用范围是大括号{}括起来的代码,锁是Synchronized括号里指定的内容。按照对象的类型可以分为类锁和对象锁。

    (1)锁对象为实例对象

    public void method(Object o) {       synchronized(o) {                 ...      }}


    上述代码锁定的就是o这个对象,只要进入以该对象为锁的任何代码都会触发同步。当有一个明确的对象作为锁时,可以直接以该对象作为锁。当没有明确的对象作为锁,只是想让一段代码同步时,可以创建一个特殊的对象来充当锁。例如:

    private byte[] lock = new byte[0];

    注:查看编译后的字节码:生成零长度的byte[]对象只需3条操作码,而Object lock = new Object()则需要7行操作码。因此使用特殊对象来充当锁,大大节省了系统的开销。

    (2)锁对象为类的Class对象

    public class Demo{  ...  public static void method(){    synchronized(Demo.class){      ...    }  }}


    上述代码是以Demo类的Class对象为锁,进入以该类任意实例对象为锁的代码都会触发同步,其效果类似于静态同步方法。

    四、synchronized的实现原理

    monitor对象
    Java中的同步代码块是使用monitorenter和monitorexit指令实现的,其中monitorenter指令插入到同步代码块的开始位置,monitorexit指令插入到同步代码块的结束位置。JVM保证每一个monitorenter都有一个monitorexit与之相对应。任何对象都有一个monitor与之相关联,当线程执行到monitorenter指令时,将会尝试获取锁对象所对应的monitor所有权,即尝试获取对象的锁;当线程执行monitorexit指令时,锁的monitor就会被释放。同步方法的实现与同步块略有不同,它依靠的是方法修饰符上的ACC_SYNCHRONIZED实现。synchronized具体的实现原理详见本人另一篇文章:
    深入理解Java中Synchronized的实现原理

    五、Synchronized与重入锁ReentrantLock的区别

    (1) 相对于ReentrantLock而言,synchronized锁是重量级锁,重量级体现在活跃性差一点。同时synchronized锁是内置锁,意味着JVM能基于synchronized锁做一些优化:比如增加锁的粒度(锁粗化)、锁消除。
    (2) 在synchronized锁上阻塞的线程是不可中断的:线程A获得了synchronized锁,当线程B也去获取synchronized锁时会被阻塞。而且线程B无法被其他线程中断(不可中断的阻塞),而ReentrantLock锁能实现可中断的阻塞。
    (3) synchronized锁释放是自动的,当线程执行退出synchronized锁保护的同步代码块时,会自动释放synchronized锁。而ReentrantLock需要显示地释放:即在try-finally块中释放锁。
    (4) 线程在竞争synchronized锁时是非公平的:假设synchronized锁目前被线程A占有,线程B请求锁未果,被放入队列中,线程C请求锁未果,也被放入队列中,线程D也来请求锁,恰好此时线程A将锁释放了,那么线程D将跳过队列中所有的等待线程并获得这个锁。而ReentrantLock能够实现锁的公平性。
    (5) synchronized锁是读写互斥并且读读也互斥,ReentrantReadWriteLock 分为读锁和写锁,而读锁可以同时被多个线程持有,适合于读多写少场景的并发。
    (6) ReentrantLock锁的是代码块,synchronized还能锁方法和类。ReentrantLock可以知道线程有没有拿到锁,而synchronized不能。

    读到这里,这篇“Java同步锁synchronized怎么使用”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网精选频道。

    --结束END--

    本文标题: Java同步锁synchronized怎么使用

    本文链接: https://lsjlt.com/news/352426.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    猜你喜欢
    • Java同步锁synchronized怎么使用
      本文小编为大家详细介绍“Java同步锁synchronized怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java同步锁synchronized怎么使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一...
      99+
      2023-07-05
    • 怎么用Java实现synchronized锁同步机制
      这期内容当中小编将会给大家带来有关怎么用Java实现synchronized锁同步机制,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。synchronized 实现原理synchronized 是通过进入和...
      99+
      2023-06-25
    • Java实现synchronized锁同步机制
      目录synchronized实现原理适应性自旋(AdaptiveSpinning)锁升级Java对象头偏向锁(BiasedLocking)偏向锁获取偏向锁释放关闭偏向锁轻量级锁(Li...
      99+
      2024-04-02
    • Java同步锁synchronized用法的最全总结
      目录一、并发同步问题二、锁的简介三、synchronized的三种应用方式1.修饰一个实例方法2.修饰一个静态方法3.修饰一个代码块(2)锁对象为类的Class对象四、synchro...
      99+
      2023-03-21
      Java同步锁 synchronized的总结
    • 怎么在java中synchronized同步
      本篇文章给大家分享的是有关怎么在java中synchronized同步,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Java是什么Java是一门面向对象编程语言,可以编写桌面应...
      99+
      2023-06-14
    • Java对象级别与类级别的同步锁synchronized语法怎么用
      本篇内容主要讲解“Java对象级别与类级别的同步锁synchronized语法怎么用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java对象级别与类级别的同步锁synchronized语法怎么...
      99+
      2023-06-29
    • java中synchronized Lock(本地同步)锁的8种情况
      目录lock1lock2lock3lock4lock5lock6lock7lock8Lock(本地同步)锁的8种情况总结与说明: * 题目: * 1.标准访问,请问是先打印邮件还是...
      99+
      2024-04-02
    • java同步锁怎么加
      在Java中,可以使用关键字`synchronized`来实现同步锁。具体有以下几种方式可以使用同步锁: 实例级别的同步锁:使用...
      99+
      2023-10-25
      java
    • Java Synchronized锁的使用详解
      目录Synchronized的用法同步示例方法同步静态方法同步代码块Synchronized的用法 在多线程并发问题中,常用Synchronized锁解决问题。Synchronize...
      99+
      2022-11-13
      Java Synchronized锁使用 Java Synchronized锁 Java Synchronized
    • Java 多线程同步 锁机制与synchronized深入解析
      打个比方:一个object就像一个大房子,大门永远打开。房子里有很多房间(也就是方法)。这些房间有上锁的(synchronized方法), 和不上锁之分(普通方法)。房门口放着一把钥...
      99+
      2022-11-15
      Java 多线程同步 锁机制
    • Java中怎么利用Synchronized实现多线程同步
      这期内容当中小编将会给大家带来有关Java中怎么利用Synchronized实现多线程同步,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。使用同步的原因 在系统中对访类要使用多线程进行访问; 在该类中有 类...
      99+
      2023-06-17
    • Java同步锁Synchronized底层源码和原理剖析(推荐)
      目录1 synchronized场景回顾2 反汇编寻找锁实现原理3 synchronized虚拟机源码3.1 HotSpot源码Monitor生成3.2 HotSpot源码之Moni...
      99+
      2024-04-02
    • Java Synchronized怎么使用
      本篇内容介绍了“Java Synchronized怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Synchronized锁优化jdk...
      99+
      2023-07-05
    • Java中怎么利用synchronized关键字实现同步机制
      Java中怎么利用synchronized关键字实现同步机制,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Java的synchronized使用方法总结1.  把sy...
      99+
      2023-06-18
    • Java对象级别与类级别的同步锁synchronized语法示例
      目录1. 对象级别的同步锁2. 类级别的同步锁3. 总结 Java synchronized 关键字 可以将一个代码块或一个方法标记为同步代码块。同步代码块是指同一时间只能有一个线程...
      99+
      2024-04-02
    • JUC中的Lock锁与synchronized同步代码块问题怎么解决
      这篇文章主要介绍“JUC中的Lock锁与synchronized同步代码块问题怎么解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“JUC中的Lock锁与synchronized同步代码块问题怎么解...
      99+
      2023-06-29
    • 死磕 java同步系列之synchronized解析
      目录问题简介实现原理原子性、可见性、有序性公平锁VS非公平锁锁优化总结彩蛋——synchronized的五种使用方式总结问题 (1)synchronized的特性? (2)synch...
      99+
      2024-04-02
    • Java synchronized同步关键字工作原理
      目录一、简介二、synchronized的特性三、synchonized的使用及通过反汇编分析其原理修饰代码块monitorenter指令monitorexit指令修饰普通方法修饰静...
      99+
      2023-02-13
      Java synchronized Java synchronized原理
    • Java并发系列之JUC中的Lock锁与synchronized同步代码块问题
      目录一、Lock锁二、锁的底层三、案例案例一:传统的synchronized实现案例二:Lock锁的实现四、Lock锁和synchronized的区别写在前边: 在Java服务端中,...
      99+
      2024-04-02
    • 如何正确的在java中使用同步锁
      这篇文章给大家介绍如何正确的在java中使用同步锁,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。同步锁分类对象锁(this)类锁(类的字节码文件对象即类名.class)字符串锁(比较特别)应用场景在多线程下对共享资源的...
      99+
      2023-05-31
      java 同步锁 ava
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作