`

可重入锁/不可重入锁

    博客分类:
  • Lock
阅读更多

原创转载请注明出处:https://agilestyle.iteye.com/blog/2443634

 

可重入锁

可重入锁指的是可重复可递归调用的锁,在外层使用锁之后,在内层仍然可以使用,并且不发生死锁(前提是同一个对象或者类)

Note:

ReentrantLock和synchronized都是可重入锁

public class TestLock {
    public synchronized void test1() throws InterruptedException {
        Thread.sleep(1000);
        System.out.println("test1 invoked...");
        test2();
    }

    public synchronized void test2() throws InterruptedException {
        Thread.sleep(1000);
        System.out.println("test2 invoked...");
    }

    public static void main(String[] args) throws InterruptedException {
        TestLock testLock = new TestLock();
        testLock.test1();
    }
}

上面的代码就是一个可重入锁的一个特点,如果不是可重入锁的话,test2可能不会被当前线程执行,可能造成死锁。 

 

不可重入锁

不可重入锁,与可重入锁相反,不可递归调用,递归调用就会发生死锁。

使用自旋锁来模拟一个不可重入锁

import java.util.concurrent.atomic.AtomicReference;

public class UnreentrantLockTest {
    private static UnreentrantLock lock = new UnreentrantLock();

    public static void main(String[] args) {
        lock.lock();

        test();

        lock.unlock();
    }

    private static void test() {
        lock.lock();

        System.out.println("test invoked...");

        lock.unlock();
    }

    private static class UnreentrantLock {
        private AtomicReference<Thread> owner = new AtomicReference<>();

        public void lock() {
            Thread currentThread = Thread.currentThread();

            for (; ; ) {
                System.out.println(owner);
                if (owner.compareAndSet(null, currentThread)) {
                    System.out.println(currentThread + " locked...");
                    return;
                }
            }
        }

        public void unlock() {
            Thread currentThread = Thread.currentThread();

            owner.compareAndSet(currentThread, null);

            System.out.println(currentThread + " unlock...");
        }
    }
}

Note:

使用原子引用来存放线程,同一个线程两次调用lock()方法,如果不执行unlock()释放锁的话,第二次调用自旋的时候就会产生死锁,这个锁是不可重入的

 

修改上述代码,将它改造成可重入锁,在执行每次操作之前,判断当前锁持有者是否是当前对象,采用state计数

import java.util.concurrent.atomic.AtomicReference;

public class ReentrantLockTest {
    private static ReentrantLock lock = new ReentrantLock();

    public static void main(String[] args) {
        lock.lock();

        test();

        lock.unlock();
    }

    private static void test() {
        lock.lock();

        System.out.println("test invoked...");

        test1();

        lock.unlock();
    }

    private static void test1() {
        lock.lock();

        System.out.println("test2 invoked...");

        lock.unlock();
    }

    private static class ReentrantLock {
        private AtomicReference<Thread> owner = new AtomicReference<>();
        private int state = 0;

        public void lock() {
            Thread currentThread = Thread.currentThread();

            if (currentThread == owner.get()) {
                state++;
                return;
            }

            for (; ; ) {
                System.out.println(owner);
                if (!owner.compareAndSet(null, currentThread)) {
                    return;
                }
            }
        }

        public void unlock() {
            Thread currentThread = Thread.currentThread();

            if (currentThread == owner.get()) {
                if (state != 0) {
                    state--;
                } else {
                    owner.compareAndSet(currentThread, null);
                }
            }
        }
    }
}

 

 

 

 

 

分享到:
评论

相关推荐

    可重入详解可重入详解

    若一个程序或子程序可以安全的被并行执行,则称其为可重入(reentrant或re-entrant)的;即,当该子程序正在运行时,可以再次进入并执行它。若一个函数是可重入的,则该函数: ...不能调用不可重入的函数。

    Go《Redis实现智能门锁(互斥锁、看门狗、读写锁、红锁、闭锁、可重入锁)》+源代码+设计资料

    Redis实现互斥锁、看门狗、读写锁、红锁、闭锁、可重入锁 - 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载...

    Java锁之可重入锁介绍

    主要介绍了Java锁之可重入锁介绍,可重入锁,也叫做递归锁,指的是同一线程外层函数获得锁之后,内层递归函数仍然有获取该锁的代码,但不受影响,需要的朋友可以参考下

    Java并发编程:用AQS写一把可重入锁

    AQS是J.U.C包下AbstractQueuedSynchronizer抽象的队列式的同步器的简称,这是一个抽象类,它定义了一套多线程访问共享资源的同步器框架,J.U.C包下的许多同步类实现都依赖于它,比如ReentrantLock/Semaphore/...

    zookeeper分布式锁实例源码

    基于zookeeper的不可重入锁Shared Lock 举例,可重入锁Shared Reentrant Lock 举例,可重入读写锁Shared Reentrant ReadWriteLock 举例

    常见的Java笔试题-JVM-JUC-Core:JUCJVM核心知识点

    可重入锁/递归锁 锁的配对 自旋锁 读写锁/独占/共享锁 Synchronized和Lock的区别 CountDownLatch/CyclicBarrier/Semaphore CountDownLatch 枚举类的使用 CyclicBarrier Semaphore 阻塞队列 SynchronousQueue ...

    Java中ReentrantLock的使用.docx

    可重入锁: 也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响。 在JAVA中ReentrantLock 和synchronized 都是可重入锁; 重入锁ReentrantLock 相对来说是...

    广联达无驱写锁工具写锁工具.zip

    深思S4 2.46 64k空锁可直接写锁 旧锁 用开发测试工具,重置设备(不要重置底层文件)。然后用无驱转换一下再写锁 32k和64k外壳是看不出来的 只能通过检测 说明: 本人不打广告,也不卖锁,没有购买链接 空锁...

    Java各种锁的使用方式及其对比

    Java提供了多种类型的锁,包括 `synchronized` 块,可重入锁,读写锁和印章锁等。这些锁可以用来控制对共享资源的访问,从而保证数据一致性和线程安全。 在程序中使用锁需要注意锁定的粒度和时长,过大的锁粒度或...

    密码锁设计

    (2)当开锁按扭开关(可设置8位或更多,其中只有4位有效,其余位为虚设)的输入代码等于所设密码时启动开锁控制电路,并且用绿灯亮、红灯灭表示开锁状态。(3)从第一个按扭触动后的5秒内若未能将锁打开,则电路...

    悲观锁和乐观锁.md

    所谓悲观锁,总是假设最坏的情况,每次去拿数据的时候都会认为别人会修改数据,造成幻读,不可重复读,脏读等情况发生。所谓乐观锁,重视假设最好的情况,每次去拿数据都认为别人不会修改,所以不会上锁,但是会在...

    基站铁塔智能门禁电控锁方案.pdf

    基站铁塔智能门禁电控锁方案 一、基站门禁管理的现状与需求 在移动互联网高速发展的今天, 移动通信已成为人们生活中不可或缺的一部 分。基站作为移动通信的重要基础设施,如何在现有规范管理基础上,进一步实 现...

    windows防锁专家

    捕获锁定窗口,将它们隐藏或结束,并可防止它们关闭系统,巧妙绕过这类程序的口令限制,直接进 入系统桌面,并解除鼠标限制等等可能的限制. 此外,Windows 防锁专家还有一些其它功能,如激活灰色按钮,查看星号密码,拖盘...

    EDA课程设计报告(基于FPGA的14位可变密码锁设计)

    2.开锁输出信号out为1表示开锁,否则不开锁。 3.输出报警信号均为1有效,分为声报警Sound the alarm (扬声器)和 light alarm(发光管), 4.14位数字密码分时操作,先预置高7位,然后再置入低7位,(顶层电路可...

    ET199写锁文件,部分广联达2018授权过期,亲测可用使用,但无写锁工具,可使用旧版写锁工具。

    给部分无法使用或过期的授权用户,本着我为人人,人人为我,使用时多安装几次,顺序为写锁,重启,授权,重启,注意查看广联达新驱动中:我的授权,

    NBIoT智能门锁设计方案.doc

    2.1.6扫码开锁 APP扫码开锁,扫码开锁功能必须通过智能锁管理平台或者APP管理端的授权认证,可 通过APP申请开锁权限,未经过授权认证不允许开门。 2。1.7实时数据上传 门锁的电量、信号强度、开关状态以及用户开门的...

    c语言跨平台互斥锁封装

    在做多线程开发时,互斥锁是必不可少的。但c语言不像c++11有标准的线程库,在各种编译器支持的平台都可以使用。而且跨平台开发中,在业务逻辑里写不同平台的兼容代码,容易造成过多的冗余,以及代码结构过于复杂的...

    电子智能锁设计任务书.docx

    防盗门木门均可安装、可与绝大多数防盗门及入户门匹配并轻松置换旧锁; 技术参数: 工作电压:DC9V,1.5V"AA"碱性电池6节 应急电源:9V层叠式电池 功耗:静态功耗 15uA、动态功耗 200mA 工作环境:工作温度:-25 ~+...

    基于单片机的电子密码锁系统的设计

    当发生破门而入等非正常开锁情况时,红外监视装置仍然工作,门打开后挡住了信号,接收器接收不到信号,此时系统报警。锁打开后还可通过按下“修改/重置”功能键,重新设置新密码。主人外出关门后可通过“修改/重置”...

    手机解锁工具

    下面列举部分品牌手机解锁教材: 一)摩托罗拉 摩托罗拉所有机锁:按menu+5+1/2 ... t2688/2988万能解锁码:19980722 c300解话机锁:20020801 ...摩托罗拉2688时间不走修复密诀:将电源1脚和8脚用漆包线短接,必杀

Global site tag (gtag.js) - Google Analytics