首页 > 编程知识 正文

可重入分布式锁,偏向锁和可重入锁

时间:2023-05-05 23:20:12 阅读:31373 作者:3703

可重入锁synchronized和Lock都是可重载的锁,也称为递归锁。 这意味着一个线程可以重复获取同一锁

这意味着,当同一线程通过外部方法获取锁定时,进入该线程的内部方法将自动获取锁定,而不会因为以前获取但未释放而阻止。

在Java中,ReentrantLock和synchronized都是可以重新锁定的,可以重新锁定的优点之一是在一定程度上避免了死锁。

synchronized 是隐式锁,Lock是显式锁

也就是说,同步解锁将自动完成

锁定解除是手动进行的

同步http://www.Sina.com/(同步代码块) package com.dongguo.sync;/* * @ author dongguo * @ date 2021/8/240024-13:58 * @ description 3360同步可重新锁定*/publiccclasssynclockdemo nemo 同步(对象) (system.out.println ) thread.currentthread ) (.getName ) ) -中层); 同步(object ) ) system.out.println ) thread.currentthread ) ).getName ) -内层); },' ThreadA ' ).start (; }运行结果: ThreadA-外层ThreadA-中层ThreadA-内层synchronized 可重入锁(同步方法) package com.dongguo.sync;/* * @ author dongguo * @ date 2021/8/240024-13:58 * @ description 3360可同步重新锁定*/publiccclasssynclockdemo } //递归公共同步void add () { number; system.out.println(number ); add (; //自己调查自己}

同步重载的实现原理每个锁对象都有一个锁计数器和指向具有该锁的线程的指针。

运行monitorenter时,如果目标锁定对象的计数器为零,则表示该计数器不保留在其他线程中。 Java虚拟机将锁定对象的保留线程设置为当前线程,并将其计数器加1。

如果目标锁定对象的计数器不为零,并且锁定对象的保留线程是当前线程,则Java虚拟机可以将该计数器加1。 否则,必须等待保持线程解除锁定。

运行monitorexit时,Java虚拟机必须将锁定对象的计数器减少1。 如果计数器为零,则表示锁定已解除。

重复锁定

33558 www.Sina.com/reentrant lock相对于同步具有以下特征

可中断

可以设定超时时间

可以设定为公平锁定

支持多个条件变量

与同步一样,支持重新导入

package com.dongguo.sync; import Java.util.concurrent.locks.lock; import Java.util.concurrent.locks.reentrant lock;/* * @ author dongguo * @ date 2021/8/240024-13:58 * @ description 3360 lock可重新锁定*/publiccclasssynclockdemo { publiplion

new Thread(() -> { try { lock.lock(); System.out.println(Thread.currentThread().getName() + "-外层"); try { lock.lock(); System.out.println(Thread.currentThread().getName() + "-中层"); try { lock.lock(); System.out.println(Thread.currentThread().getName() + "-内层"); } finally { lock.unlock(); } } finally { lock.unlock(); } } finally { lock.unlock(); } }, "ThreadA").start(); }}运行结果:ThreadA-外层ThreadA-中层ThreadA-内层

注意:加锁几次就要解锁几次

package com.dongguo.sync;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * @author Dongguo * @date 2021/8/24 0024-13:58 * @description: */public class SyncLockDemo1 { public static void main(String[] args) { Lock lock = new ReentrantLock(); new Thread(() -> { try { lock.lock(); System.out.println(Thread.currentThread().getName() + "-外层"); try { lock.lock(); System.out.println(Thread.currentThread().getName() + "-中层"); try { lock.lock(); System.out.println(Thread.currentThread().getName() + "-内层"); } finally { lock.unlock(); } } finally { //lock.unlock(); //这里故意注释,实现加锁次数和释放次数不一样 //由于加锁次数和释放次数不一样,第二个线程始终无法获取到锁,导致一直在等待。 } } finally { lock.unlock(); } }, "t1"); new Thread(() -> { try { lock.lock(); System.out.println("t2获得lock锁"); } finally { lock.unlock(); } }, "t2"); }}

由于t1获取锁与释放锁的次数不同,t2无法获得lock锁

ReentrantLock递归锁 package com.dongguo.sync;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * @author Dongguo * @date 2021/8/24 0024-13:58 * @description: */public class SyncLockDemo { Lock lock = new ReentrantLock(); public static void main(String[] args) { new SyncLockDemo().add(); } public long number = 0; //递归 public void add(){ try { lock.lock(); number++; System.out.println(number); add();//自己调自己 } finally { lock.unlock(); } }}

运行结果:

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。