首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

理解Java中锁的状态与优化

Java中的乐观锁一般都是通过CAS来实现的,如Atom系列的并发工具包类。在nosql的数据里面elasticsearch就是典型的使用乐观锁来更新每条数据。...关于Java对象的存储结构 提到锁的状态,这里必须要提一下Java对象的存储结构,总体上来说每个实例对象由三部分组成:对象头,实例数据,对其填充。...轻量级锁 轻量级锁,顾名思义,相比重量级锁,其加锁和解锁的开销会小很多。重量级锁之所以开销大,关键是其存在线程上下文切换的开销。而轻量级锁通过JAVA中CAS的实现方式,避免了这种上下文切换的开销。...当compare失败的时候(理解成没有拿到"锁"),当compare成功的时候,可以直接对互斥资源进行修改(就好像拿到了“锁一样”),此外,轻量级锁失败的时候线程不会被挂起,会通过自旋的方式再次尝试获取...锁优化 (1)锁的可重入性,在synchronized方法中,可以继续调用该实例的其他的synchronized方法,这就是可重入性。

56940

深入理解Java中的锁(二)

当有线程进来时,会先判断count的值,如果count为0说明锁没有被占用 然后通过CAS操作进行抢锁 如果抢到锁则count的值会加1,同时将owner设置为当前线程的引用 如果count不为0同时owner...指向当前线程的引用,则将count的值加1 如果count不为0同时owner指向的不是当前线程的引用,则将线程放入等待队列waiters中 如果CAS抢锁失败,则将线程放入等待队列waiters中 当线程使用完锁后...,会释放其持有的锁,释放锁时会将count的值减1,如果count值为0则将owner设为null 如果count值不为0则会唤醒等待队列头部的线程进行抢锁 手动实现ReentrantLock代码示例:...,锁消除,偏向锁,轻量级锁) 锁的释放由虚拟机完成,不用人工干预,降低了死锁的可能性 缺点: 悲观的排他锁,无法实现锁的高级功能如公平锁,读写锁等 Lock: 优点:可以实现synchronized无法实现的锁的高级功能如公平锁...,读写锁等,同时还可以实现更多的功能  缺点:需手动释放锁unlock,使用不当容易造成死锁 结论: 两者都是可重入锁,synchronized可以类比为傻瓜相机,提供了固定的功能,而Lock可以类比为单方

33220
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    深入理解Java中的锁(三)

    同一时间,两把锁不能被不同线程持有。读写锁适合读取操作多于写入操作的场景,改进互斥锁的性能,比如集合的并发安全性改造,缓存组件等。...的值,如果readCount为0说明读锁未被占用 然后判断writeCount的值,如果writeCount为0,说明写锁未被占用 然后通过CAS操作进行抢锁将writeCount值加1,如果抢到锁则将...,即锁降级 如果写锁不是被当前线程占用,则将线程放入等待队列 当有写线程释放锁时,会将writeCount的值减1,如果writeCount的值为0,则将owner设为null同时唤醒等待队列头部的线程出队列进行抢锁操作...waiters.poll(); // 将当前线程从队列中移除 WaitNode next = waiters.peek(); if (next !...锁降级指的是写锁降级为读锁,是指持有写锁的同时,再获取读锁,随后释放写锁的过程。

    40820

    深入理解Java中的锁(一)

    Java中锁的概念 自旋锁 :是指当一个线程在获取锁的时候,如果锁已经被其他线程获取,那么该线程将循环等待,然后不断判断锁是否能够被成功获取,直到获取到锁才会退出循环。...不可重入锁 :线程拿到一把锁后,不可以自由进入同一把锁所同步的代码 公平锁 :争抢锁的顺序,按照先来后到的顺序 非公平锁 :争抢锁的顺序,不按照先来后到的顺序 Java中几种重要的锁实现方式:synchronized...要了解synchronized加锁在JVM中是如何实现的,就有必要了解Java对象在JVM中到底是如何存储的。我们知道JVM中在方法区存储对象的引用,在堆中存储的对象实例。...我们知道Java中每个对象都会有一个对象监视器(Object Monitor, 即管程),而升级为重量级锁就需要用到这个Object Monitor。...偏向锁会偏向于第一个获得它的线程,如果在接下来的执行过程中,该锁没有被其他的线程获取,则持有偏向锁的线程将永远不需要同步。

    40610

    Java中的锁

    下面我们看一下Lock接口提供的方法,便于更好的阅读,请读者可先查看java.util.concurrent.locks.Lock中的源码,跟着源码中的注释一起理解接口中的方法。...2.7.2 队列同步器AQS 本章节是介绍Java中的锁,也可以换个说法是讲Java中的同步组件,典型代表有ReentrantLock、CountDownLatch、ReentrantReadWriteLock...2.7.3 显示锁 本小结介绍Java中两个比较重要的显示锁的使用,一个是ReentrantLock,另一个是ReentrantReadWriteLock。...可能读者会有疑问,因为几乎所有资料都会把ReentrantLock视为重入锁,没错,从名字上看他确实是可重入性的锁,之所以小标题使用显示锁是因为,我们知道在JAVA中ReentrantLock 和synchronized...重入锁,顾名思义,是有重入性的,这里面有两个角色,一个是谁可以重新进入,另一个是他可以重新进入哪里。我们可以这样理解,重入是指线程在获取锁后可以在此获取到该锁而不会被阻塞的特性,称为重入性。

    34730

    Java中的锁

    ---- 欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。...---- 欢迎跳转到本文的原文链接:https://honeypps.com/java/locks-in-java/ 在学习或者使用Java的过程中进程会遇到各种各样的锁的概念:公平锁、非公平锁、自旋锁...这里整理了Java中的各种锁,若有不足之处希望大家在下方留言探讨。 WARNING:本文适合有一定JAVA基础的同学阅读。...##自旋锁 Java的线程是映射到操作系统的原生线程之上的,如果要阻塞或唤醒一个线程,都需要操作系统来帮忙完成,这就需要从用户态转换到核心态中,因此状态装换需要耗费很多的处理器时间,对于代码简单的同步块...---- 参考资料 《深入理解Java虚拟机》周志明著 《Java并发编程的艺术》方腾飞等著 Java对象大小内幕浅析 JVM内部细节之一:synchronized关键字及实现细节(轻量级锁Lightweight

    38220

    Java中的锁

    点击上方 好好学java ,选择 星标 公众号 重磅资讯、干货,第一时间送达今日推荐:用好Java中的枚举,真的没有那么简单!...2.2、synchronized ★synchronized通过锁机制实现同步。 ” 先来看下利用synchronized实现同步的基础:Java中的每一个对象都可以作为锁。...2.2.3 锁存放的位置 锁标记存放在Java对象头的Mark Word中。 ? Java对象头长度 ? 32位JVM Mark Word 结构 ? 32位JVM Mark Word 状态变化 ?...image.png 2.3、CAS ★CAS,在Java并发应用中通常指CompareAndSwap或CompareAndSet,即比较并交换。...3、Java中的锁实现 3.1、队列同步器(AQS) ★队列同步器AbstractQueuedSynchronizer(以下简称同步器),是用来构建锁或者其他同步组件的基础框架。

    1.1K31

    Java中的锁

    讨论J.U.C包中locks下面的类(包括接口) 锁主要是用来控制多个线程访问共享资源的一种方式,通常情况下,一个锁可以防止在同一时间内多个线程同时访问共享资源(读写锁除外,读写锁在同一时间内...公平与非公平获取锁:公平指的是在绝对时间上,先对锁进行请求的线程(等待时间最长的线程优先获取锁)首先获取锁,那么这个锁是公平的,反之,则是非公平的。 ①....锁的重进入 如果要实现锁的重进入,那么就就绪解决两个问题: 锁的获取:要获取锁,那么锁就需要去检查获取该锁的线程是否是已获取此锁的线程(也就是是否是当前线程占有此锁),如果是,那么获取成功;如下代码是非公平获取锁的方式...,在这段代码中,仅仅在if条件中多了一个hasQueuedPredecessors()方法,此方法就是判断在同步队列中,当前节点是否有前驱节点(即有比当前线程更早的获取锁的线程),因此当hasQueuedPredecessors...LockSupport类 LockSupport类位于在J.U.C.locks包中,它主要是定义了一些公共静态方法,这些方法提供了最基本的线程阻塞和唤醒功能。

    60990

    java中的锁

    看来确实是要学习的最好方式是要带着问题去学,并且解决问题。 在java中锁主要两类:内部锁synchronized和显示锁java.util.concurrent.locks.Lock。...确实是不一样的,此时获取的锁已经不是this了,而this对象指向的class,也就是类锁。因为Java中的类信息会加载到方法常量区,全局是唯一的。这其实就提供了一种全局的锁。...java中对内置锁也提供了一些实现,主要的特点就是java都是对象,而每个对象都有锁,所以可以根据情况选择用什么样的锁。...或者像java并发编程>中说的那样,concurrent中的lock是对内部锁的一种补充,提供了更多的一些高级特性。...为了更好理解可中断的锁操作,写了一个demo来理解。

    1.4K90

    Java中的锁

    乐观锁 认为自己在使用数据时不会有别的线程修改数据或资源,所以不会添加锁。 在Java中是通过使用无锁编程来实现,只是在更新数据的时候去判断,之前有没有别的线程更新了这个数据。...如果这个数据已经被其他线程更新,则根据不同的实现方式执行不同的操作,比如放弃修改、重试抢锁等 判断规则 版本号机制Version 最常采用的是CAS算法,Java原子类中的递增操作就通过CAS自旋实现的...锁的是当前对象this,被锁定后,其他的线程都不能进入到当前的对象的其他synchronized方法 类中的普通方法和同步锁方法无关 new 两个对象后,就不是同一把锁了 类中的静态同步方法 对于普通同步方法...如果是1个有synchronized修饰的递归调用方法,程序第二次进入被自己阻塞了那岂不是无解了 所以Java中RenntrantLock和synchronized都是可重入锁,可重入锁的一个优点是可以定成都避免死锁...在Java虚拟机(HotSpot)中,monitor是ObjectMonitor实现的

    26310

    java redis锁_Java中Redis锁的实现

    大家好,又见面了,我是你们的朋友全栈君。 由于具体业务场景的需求,需要保证数据在分布式环境下的正确更新,所以研究了一下Java中分布式锁的实现。...Java分布式锁的实现方式主要有以下三种: 数据库实现的乐观锁 Redis实现的分布式锁 Zookeeper实现的分布式锁 其中,较常用的是前两种方式,但是数据库实现方式需要较多的数据库操作,所以最终选择的是用...而当这个key在redis中已有记录时,则不会重新插入记录,这样的话,便可以实现分布式锁的基本功能。且为其设置过期时间,并加入UniqueId的check,避免了上述提及的两个问题。...上述的解锁代码中,在解锁之前先验证了UniqueId,然后采用del方法来释放锁,但是由于get和del是两次请求,而不是一个原子操作,所以这之间仍存在并发的问题。...在有些较看重数据的正确性的场景中,即使Redis锁超时,只要检测到机器仍在正常运行Redis锁就不应该被释放,而应该被续期,这些,都是redis锁在更复杂的场景中所需要考虑的。留待以后继续研究。

    2.1K20

    java 读写锁_Java中的读写锁「建议收藏」

    一、读写锁 1、初识读写锁 a)Java中的锁——Lock和synchronized中介绍的ReentrantLock和synchronized基本上都是排它锁,意味着这些锁在同一时刻只允许一个线程进行访问...并发包中对ReadWriteLock接口的实现类是ReentrantReadWriteLock,这个实现类具有下面三个特点 ①具有与ReentrantLock类似的公平锁和非公平锁的实现:默认的支持非公平锁...这个特点也在源码中实现。 c)写锁writeLock ①上面说到过,读写锁是支持重入的锁,而对于写锁而言还是排他的,这样避免多个线程同时去修改临界资源导致程序出现错误。...③写锁的释放源码 写锁的释放和ReentrantLock的锁释放思路基本相同,从源码中可以看出来,每次释放都是减少写状态,直到写状态值为0(exclusiveCount(nextc) == 0)的时候释放写锁...在同一时刻的竞争队列中,如果没有写线程想要获取读写锁,那么读锁总会被读线程获取到(然后更新读状态的值)。每个读线程都可以重入的获取读锁,而对应的获取次数保存在本地线程中,由线程自身维护该值。

    2.9K20

    Java中的各种锁

    参考:https://tech.meituan.com/2018/11/15/java-lock.html 乐观锁 VS 悲观锁 悲观锁认为自己在使用数据的时候一定有别的线程来修改数据,因此在获取数据的时候会先加锁...Java中,synchronized关键字和Lock的实现类都是悲观锁。 乐观锁认为自己在使用数据时不会有别的线程修改数据,所以不会添加锁,只是在更新数据的时候去判断之前有没有别的线程更新了这个数据。...乐观锁在Java中是通过使用无锁编程来实现,最常采用的是CAS算法,Java原子类中的递增操作就通过CAS自旋实现的。 悲观锁适合写操作多的场景,先加锁可以保证写操作时数据正确。...乐观锁适合读操作多的场景,不加锁的特点能够使其读操作的性能大幅提升。 通过调用方式示例,我们可以发现悲观锁基本都是在显式的锁定之后再操作同步资源,而乐观锁则直接去操作同步资源。...java.util.concurrent包中的原子类就是通过CAS来实现了乐观锁。 CAS算法涉及到三个操作数: 需要读写的内存值 V。 进行比较的值 A。 要写入的新值 B。

    36610

    Java中锁的分类

    Java中锁的分类一、介绍在Java中的锁可以分为以下这四类可重入锁、不可重入锁乐观锁、悲观锁公平锁、非公平锁互斥锁、共享锁二、详解1)可重入锁、不可重入锁当一个线程持有一个锁后,又想再持有这个锁时,发生的情况...如果数据未被修改,乐观锁会直接进行更新。常见的乐观锁实现包括版本号机制和CAS机制。Java中的Atomic相关的类,底层正是使用的CAS。...在Java中,synchronized和Lock相关的类都属于悲观锁。他们主要的区别是,由于悲观锁会造成锁的占用和线程的切换,故占用较大。...非公平锁:不管先来后到,线程统一进行竞争,有CPU调度进行分配。Java中的synchronized就是一款非公平锁,而Lock锁两者皆可,是可以进行设置的。...4)互斥锁、共享锁线程持有锁后,其他线程同时持有这把锁,通过这样的特性进行区分互斥锁:不同的线程不能同时持有同一把锁共享锁:不同的线程允许同时持有同一把锁在Java中,synchronized关键字就是一把互斥锁

    10800

    java中的锁分类

    java中的锁分类 java中的锁 公平锁/非公平锁 公平锁是指多个线程按照申请锁的顺序来获取锁。 非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁。...互斥锁在Java中的具体实现就是ReentrantLock 读写锁在Java中的具体实现就是ReadWriteLock 乐观锁/悲观锁 悲观锁是悲观的认为,不加锁的并发操作一定会出问题 乐观锁则认为对于同一个数据的并发操作...从上面的描述我们可以看出,悲观锁适合写操作非常多的场景,乐观锁适合读操作非常多的场景,不加锁会带来大量的性能提升。 悲观锁在Java中的使用,就是利用各种锁。...乐观锁在Java中的使用,是无锁编程,常常采用的是CAS算法,典型的例子就是原子类,通过CAS自旋实现原子操作的更新。...自旋锁 在Java中,自旋锁是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁(比如cas),这样的好处是减少线程上下文切换的消耗,缺点是循环会消耗CPU。

    47520

    Java中的锁分类

    在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类。...互斥锁在Java中的具体实现就是ReentrantLock 读写锁在Java中的具体实现就是ReadWriteLock 乐观锁/悲观锁 乐观锁与悲观锁不是指具体的什么类型的锁,而是指看待并发同步的角度。...从上面的描述我们可以看出,悲观锁适合写操作非常多的场景,乐观锁适合读操作非常多的场景,不加锁会带来大量的性能提升。 悲观锁在Java中的使用,就是利用各种锁。...乐观锁在Java中的使用,是无锁编程,常常采用的是CAS算法,典型的例子就是原子类,通过CAS自旋实现原子操作的更新。...自旋锁 在Java中,自旋锁是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,这样的好处是减少线程上下文切换的消耗,缺点是循环会消耗CPU。

    94720
    领券