广告
返回顶部
首页 > 资讯 > 精选 >synchronized和ReentrantLock的基本原理是什么
  • 296
分享到

synchronized和ReentrantLock的基本原理是什么

2023-06-15 16:06:32 296人浏览 薄情痞子
摘要

这篇文章主要介绍“synchronized和ReentrantLock的基本原理是什么”,在日常操作中,相信很多人在synchronized和ReentrantLock的基本原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作

这篇文章主要介绍“synchronized和ReentrantLock的基本原理是什么”,在日常操作中,相信很多人在synchronized和ReentrantLock的基本原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”synchronized和ReentrantLock的基本原理是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

 一、java锁的类型

java的有这么几类。

乐观锁和悲观锁

  • 乐观锁就是JVM认为不通过加锁也能保证并发的正确性。典型实现是诸如AtomicInteger的实现。

  • 悲观锁就是需要加锁互斥。典型实现是Synchronized(Synchronized属于乐观锁还是悲观锁其实跟具体实现有关,大部分场景下都是悲观锁)和ReentrantLock。

可重入和不可重入

  • 可重入是指当一个线程获取了锁,但是没有释放,这个线程又要获取这个锁,仍然能获取成功。Synchronized和ReentrantLock都是可重入锁。

  • 不可重入是可重入的否命题,这样自己会把自己死锁。应该没有这样的实现。

公平锁和非公平锁

  • 公平锁是先请求锁的线程肯定先获得锁,也就是FIFO。公平说是不是就是合理的?可能也不一定,因为这会造成上下文的切换。ReentrantLock默认是非公平锁,但是可以通过构造方法构造公平锁实例。

  • 非公平锁是新来的线程有优先获得锁的机会,也就是可以插队。合理吗?可能也不合理,因为这可能造成“饿死”现象:在排队的旧的线程总是获取不到锁。Sysnchronized其实就是非公平锁。

排他锁和共享锁

  • 排他锁是一个线程获得锁之后,其他线程不能再获得锁。大多数场景下都是排他锁。

  • 共享锁是指多个线程可以同时获得锁。常见的是多个线程可以同时获得读锁。

二、synchronized

synchronized基本原理是通过CPU指令实现的。在jdk1.6之前是很重的锁。因为java的多线程操作系统的线程是一一对应的。当java线程阻塞的时候需要切换到内核态的线程进行阻塞,唤醒的时候又要从内核态切换到用户态,进行了很重的上下文切换。那么能不能当一个线程获取不到锁的时候不阻塞呢?自旋可以吗?这样就有了synchronized的四种实现:无锁、偏向锁、轻量锁、重量锁。

synchronized锁的是java的对象头,再详细点是mark Word

synchronized和ReentrantLock的基本原理是什么

无锁

这个没有什么好说的。没有将这个对象通过synchronized包括。

偏向锁

当只有一个线程在访问锁的时候,会在mark  word中通过CAS的方式设置当前线程的threadId。如果成功的话,加锁成功(由于只有一个线程,肯定成功)。这样当这个线程再次请求锁的时候,看mark  word的thread  id和自己是否相同,如果相同加锁成功。注意,它是没有解锁操作的。如果是另一个线程也来了,由于上一个线程没有解锁操作,这个新线程的CAS肯定失败。这时当JVM没有字节码要执行的时候(全局安全点),会检查上一个线程有没有结束,如果结束,则通过CAS将mark  word中的thread id字段更新为新线程的threadId。如果上一个线程没有结束,这就存在并发了。偏向锁无法完成使命,需要升级为轻量锁。

轻量锁

接着上面偏向锁的上一个线程A和新的线程B的例子。JVM此时进行一下线程A对mark word的操作。将mark  word拷贝到当前线程的栈空间中,CAS操作mark word的指针指向这个栈空间的地址,CAS操作当前线程的栈空间再加一个指向mark  word的指针,这两个操作成功后,其实第一个CAS成功就是成功,这样线程A就获得了锁,升级成为了轻量锁。线程B会自旋等待线程A的释放。线程A怎么释放锁呢?只要将第一个CAS操作的指针(mark  word指向线程栈的指针)释放了就可以了,线程B自旋检测mark  word的指向,去抢占锁。如果此时又来一个线程C呢?是不是也自旋?可以同时有几个线程自旋?线程B能自旋多少次?这些都是有JVM参数可配置的。

synchronized和ReentrantLock的基本原理是什么

重量锁

这个其实也没什么好说的。存在并发访问时,直接将线程切换到内核态阻塞。

三、ReentrantLock

ReentrantLock是通过AQS(AbstractQueuedSynchronizer)实现的。需要解决的问题:

需要有个状态表示这个lock对象是不是被抢占了,如果可重入的话,被这个线程抢占了多少次。这个状态标识其实就是AQS的state成员变量。对state的操作肯定要线程安全。可以通过CAS解决。

protected final boolean tryAcquire(int acquires) {     final Thread current = Thread.currentThread();     int c = getState();     if (c == 0) {         // 这个是公平锁的实现。需要判断队列中有没有等待的线程,         // 如果没有才进行CAS抢占             if (!hasQueuedPredecessors() &&             compareAndSetState(0, acquires)) {             setExclusiveOwnerThread(current);             return true;         }     }     // 这里就是可重入逻辑     else if (current == getExclusiveOwnerThread()) {         int nextc = c + acquires;         if (nextc < 0)             throw new Error("Maximum lock count exceeded");         setState(nextc);         return true;     }     return false; }

多个线程同时抢占lock,只有一个线程能成功,其他线程怎么排队呢?排队的线程怎么抢占锁呢?这就用到了一个队列。这个队列的插入是通过自旋和CAS实现的。

private node addWaiter(Node mode) {     Node node = new Node(mode);     // 循环尝试     for (;;) {         Node oldTail = tail;         if (oldTail != null) {             // 无锁修改前驱指针             node.setPrevRelaxed(oldTail);             // CAS修改tail             if (compareAndSetTail(oldTail, node)) {                 // 修改后续指针                 oldTail.next = node;                 return node;             }         } else {             initializeSyncQueue();         }     } }

排队的线程抢占lock呢?

final boolean acquireQueued(final Node node, int arg) {     boolean interrupted = false;     try {         for (;;) {             final Node p = node.predecessor();             // 如果前驱节点是头节点,并且获取锁成功,直接返回。             // 但是大多数情况,可能运气没这么好             if (p == head && tryAcquire(arg)) {                 setHead(node);                 p.next = null; // help GC                 return interrupted;             }             // 是否需要阻塞             if (shouldParkAfterFailedAcquire(p, node))                 // 这里阻塞                 interrupted |= parkAndCheckInterrupt();         }     } catch (Throwable t) {         cancelAcquire(node);         if (interrupted)             selfInterrupt();         throw t;     } }

怎么唤醒上面阻塞的线程呢?这就要看下释放逻辑。

public final boolean release(int arg) {     // 释放lock     if (tryRelease(arg)) {         Node h = head;         if (h != null && h.waitStatus != 0)             unparkSuccessor(h);  // 唤醒头结点的后续节点。注意头结点是虚节点,没有实在意义         return true;     }     return false; }

到此,关于“synchronized和ReentrantLock的基本原理是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: synchronized和ReentrantLock的基本原理是什么

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

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

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • synchronized和ReentrantLock的基本原理是什么
    这篇文章主要介绍“synchronized和ReentrantLock的基本原理是什么”,在日常操作中,相信很多人在synchronized和ReentrantLock的基本原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作...
    99+
    2023-06-15
  • Synchronized 和 ReentrantLock 的实现原理及区别
    目录前言考点分析知识扩展ReentrantLock 源码分析JDK 1.6 锁优化自适应自旋锁锁升级总结前言 在 JDK 1.5 之前共享对象的协调机制只有 synchro...
    99+
    2022-11-13
  • Synchronized 与 ReentrantLock 的区别是什么
    这篇文章将为大家详细讲解有关Synchronized 与 ReentrantLock 的区别是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。可重入性:从名字上理解,ReenTrantLo...
    99+
    2023-06-19
  • 在java中synchronized和ReentrantLock区别是什么
    java中synchronized和ReentrantLock区别:synchronized是关键字,而ReentrantLock是类。ReentrantLock比synchronized更灵活。ReentrantLock可以对获取锁的等待...
    99+
    2022-10-11
  • ReentrantLock核心原理是什么
    本篇内容介绍了“ReentrantLock核心原理是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!&n...
    99+
    2022-10-19
  • jQuery的基本原理是什么
    这篇文章主要介绍“jQuery的基本原理是什么”,在日常操作中,相信很多人在jQuery的基本原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”jQuery的基本原理是...
    99+
    2022-10-19
  • Nginx的基本概念和原理是什么
    这篇文章将为大家详细讲解有关Nginx的基本概念和原理是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、Nginx基本概念(engine x)是一个高性能的HTTP和反向代理web服务器,同时也提供...
    99+
    2023-06-29
  • Rails基本原理是什么
    这篇文章主要介绍“Rails基本原理是什么”,在日常操作中,相信很多人在Rails基本原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Rails基本原理是什么”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-06-17
  • SpringSecurity基本原理是什么
    小编给大家分享一下SpringSecurity基本原理是什么,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!一、SpringSecurity 本质SpringSecurity 本质是一个过滤器链;从启动是可以获取到(加载)过...
    99+
    2023-06-15
  • Synchronized的底层实现原理是什么
    Synchronized的底层实现原理是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。(1)给静态方法加锁public&n...
    99+
    2022-10-19
  • docker技术的基本原理是什么
    Docker技术的基本原理是利用容器化技术实现应用程序的隔离和封装。其主要原理如下:1. 命名空间(Namespace):Docke...
    99+
    2023-10-10
    docker
  • 香港vps的基本原理是什么
    香港VPS技术是包括有虚拟化,容器等,每个VPS都能够分配一个独立的IP,独立的操作系统,将不同VPS进行不同的配置,用程序模拟出独占的体验来。是介于虚拟的主机与独立的主机两种间的服务器,与虚拟的主机一样采用的是虚拟的技术,有具有虚拟主机所...
    99+
    2022-10-16
  • JVM中Synchronized作用及原理是什么
    这篇文章主要介绍“JVM中Synchronized作用及原理是什么”,在日常操作中,相信很多人在JVM中Synchronized作用及原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JVM中Synch...
    99+
    2023-07-05
  • colspan基本工作原理是什么
    这篇文章主要介绍了colspan基本工作原理是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇colspan基本工作原理是什么文章都会有所收获,下面我们一起来看看吧。 跨度...
    99+
    2022-10-19
  • sql注入基本原理是什么
    这篇文章主要介绍了sql注入基本原理是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。SQL注入基本原理WEB技术发展日新月异,但是徒手拼...
    99+
    2022-10-18
  • 960 Grid System基本原理是什么
    这篇文章主要介绍960 Grid System基本原理是什么,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!960 Grid System 基本原理不要编辑960.css 不要编辑960.css文件,如果你修...
    99+
    2023-06-08
  • Java synchronized偏向锁的核心原理是什么
    本篇内容主要讲解“Java synchronized偏向锁的核心原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java synchronized偏向锁的核心原理是什...
    99+
    2023-06-29
  • ORACLE 11G DATA GUARD基本原理是什么
    本篇内容主要讲解“ORACLE 11G DATA GUARD基本原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“ORACLE 11G DATA GUAR...
    99+
    2022-10-18
  • MySQL读写分离基本原理是什么
    本篇内容主要讲解“MySQL读写分离基本原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MySQL读写分离基本原理是什么”吧!一、读写分离工作原理在一些...
    99+
    2022-10-19
  • ERP与PDM集成基本原理是什么
    这篇文章的内容主要围绕ERP与PDM集成基本原理是什么进行讲述,文章内容清晰易懂,条理清晰,非常适合新手学习,值得大家去阅读。感兴趣的朋友可以跟随小编一起阅读吧。希望大家通过这篇文章有所收获! 1企业资源计划(ERP)概述&nbs...
    99+
    2023-06-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作