当前位置: 首页 > 科技观察

说说Java中的锁

时间:2023-03-21 00:00:38 科技观察

1.偏向锁,轻量级锁,重量级锁。这三种锁特指同步锁的状态。锁状态由java对象的headermarkworld标识。偏向锁有时候我们会加锁,但实际上不存在竞争,所以不需要加锁,标记一下即可,这就是偏向锁的思想。如果一个对象在初始化后没有被任何线程访问过,那么它就是可偏置的。当第一个线程访问它时,记录这个线程。如果下次还是被这个线程访问,因为是这个锁的拥有者是有偏见的,所以直接获取锁的开销很小。如果轻量级锁是java的多个线程交替同步访问,不是同时竞争,或者竞争时间较短,使用CAS(CompareAndSet)方法轮询获取锁,无需上下文切换。重量级锁是必要的。轻量级锁是指原始的偏向锁。这时,一个不是偏向锁拥有者的线程访问该对象,则偏向锁升级为轻量级锁,即通过轮询获取锁,不阻塞。重量级锁对于竞争激烈的场景,使用轻量级锁需要等待很长时间才能空转。这时候就适合重量级锁。它是使用重量级锁的同步机制实现的,开销比较大。锁升级总结:偏向锁的性能在没有CAS操作的情况下最好。轻量级锁使用CAS和自旋避免重量级操作,性能次之。重量级锁是使用系统实现的,需要上下文切换。最后,性能是最差的。2.可重入锁/不可重入锁可重入锁是获取锁的线程。如果没有释放锁,可以重新获取锁。不可重入锁是指线程获得锁后,只有释放锁后才能再次获得锁。ReentrantLock是一个可重入锁。3.共享锁和独占锁共享锁是可以被多个线程同时占用的锁,而独占锁只能被一个线程占用。我们常用的读写锁,读锁是共享锁,可以被多个线程同时占用,写锁是排他锁,只能被一个线程占用。4.公平锁和非公平锁如果锁已经被占用,后续获取锁的线程会等待并开始排队。如果锁被释放,则等待时间最长的线程获得锁。这是公平锁和非公平锁。在某些情况下会允许跳队。5.悲观锁和乐观锁悲观锁是在获取资源之前先获取锁,然后再进行操作,从而保证其他想操作的线程因为没有获取到锁而无法操作。乐观锁倾向于认为竞争并不激烈。操作资源前不需要获取锁,而是直接使用CAS操作,即更新时判断该值是否为获取到的原始值,如果是则直接修改(判断和改变都是原子的operation),如果不是则重试,不独占时资源修改完成。6、自旋锁和非自旋锁自旋锁的概念是线程如果得不到锁,不会阻塞或释放CPU资源,而是采用循环等待的方式不断获取锁。这种方法称为自旋。我的理解是不停止循环判断是否释放锁;对于非自旋锁,如果没有获取到锁,就会进入阻塞或者做其他事情。7、可中断锁和不可中断锁java中synchronized关键字修饰的锁是不可中断锁。线程一旦申请了锁,获取到锁后逻辑已经执行完毕,就不能被中断。ReentrantLock可以打断锁。在获取锁的过程中,可以中断。您不必等待其他线程释放锁就可以获取锁。