基本锁的理解(待补充)

简介: 可重入锁允许同一线程多次获取同一锁而不致死锁;不可重入锁则不允许递归锁定,连续调用会致死锁。死锁发生在多进程争夺资源导致僵局。读锁允许多线程并发读取,写锁则排他。自旋锁通过循环等待获取锁;共享锁用于只读操作;排它锁用于数据修改;闭锁延迟线程直至状态终止;信号量控制对资源的访问,未获信号量的线程会进入睡眠状态。

==可重入锁==:当一个线程获取一个对象上的锁的时候,会自动获取该对象的其他锁,而其他线程不可获取该对象的任何锁(一般都是可重复锁)
可重入锁的代码示例:

public class Lock{
   
    boolean isLocked = false;
    Thread  lockedBy = null;
    int lockedCount = 0;
    public synchronized void lock()
            throws InterruptedException{
   
        Thread thread = Thread.currentThread();
        while(isLocked && lockedBy != thread){
   
            wait();
        }
        isLocked = true;
        lockedCount++;
        lockedBy = thread;
    }
    public synchronized void unlock(){
   
        if(Thread.currentThread() == this.lockedBy){
   
            lockedCount--;
            if(lockedCount == 0){
   
                isLocked = false;
                notify();
            }
        }
    }
}

==不可重入锁==:当一个线程获取一个对象上外层方法的锁的时候,如果接下来的方法又需要获取另一个锁,则需要先等待锁释放才能获取下一个
不可重入锁的代码示例:

public class Lock{
   
    private boolean isLocked = false;
    public synchronized void lock() throws InterruptedException{
   
        while(isLocked){
       
            wait();
        }
        isLocked = true;
    }
    public synchronized void unlock(){
   
        isLocked = false;
        notify();
    }
}

如果再同一个方法里,连续调用两次 lock() 方法,会发生死锁。

==死锁==: 多个进程在运行过程之中因争夺资源而造成的一种僵局

==读锁==: 可以共享,多个线程可以同时拥有读锁
==写锁==: 只能只有一个线程拥有,而且获取写锁的时候其他线程都已经释放了读锁,该线程获取写锁之后,其他线程不能再获取读锁。简单的说就是写锁是排他锁,读锁是共享锁。Java中实现读写锁的类是:ReentrantReadWriteLock;
保证一定能读到最新数据,修改期间,写锁是一个排它锁(互斥锁、独享锁),读锁是一个共享锁
写锁没释放读锁必须等待
读 + 读 :相当于无锁,并发读,只会在Redis中记录好,所有当前的读锁。他们都会同时加锁成功
写 + 读 :必须等待写锁释放
写 + 写 :阻塞方式
读 + 写 :有读锁。写也需要等待
只要有读或者写的存都必须等待

==自旋锁==:是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。

==共享锁==:用于不更改数据的、只读、查询等操作,如 SELECT 语句,读文件等。获取共享锁的事务只能读数据,不能修改数据。

==排它锁=:用于数据的修改,比如 INSERT,UPDATE,或 DELETE,同一资源在同一时间只能有一个用户获得排它锁。

==闭锁==:闭锁是一种同步工具类,可以延迟线程的进度直到其到达终止状态;

==信号量==:和自旋锁一样,信号量也是保护临界资源的一种有用方法。信号量只有当得到信号量时,进程或者线程才能够进入临界区,执行临界代码。

信号量与自旋锁的最大不同点在于,当一个进程试图去获取一个已经锁定的信号量时,该进程不会像自旋锁一样在自旋忙等待,而是会将自身加入一个等待队列中去睡眠,直到其他进程释放信号量后,处于等待队列中的进程才会被唤醒。当进程唤醒之后,就立刻重新从睡眠的地方开始执行,又一次试图获得信号量,当获得信号量后,程序继续执行。

所以,从信号量的原理上来说,没有获得信号量的函数可能睡眠。这就要求只有能够睡眠的进程才能够使用信号量,不能睡眠的进程不能使用信号量。例如中断处理程序中,由于中断需要立刻完成,所以不能睡眠,也就是说在中断处理程序中不能使用信号量。

相关文章
|
7月前
|
人工智能 自然语言处理 数据可视化
AutoAgents:比LangChain更激进的AI开发神器!自然语言生成AI智能体军团,1句话搞定复杂任务
AutoAgents 是基于大型语言模型的自动智能体生成框架,能够根据用户设定的目标自动生成多个专家角色的智能体,通过协作完成复杂任务。支持动态生成智能体、任务规划与执行、多智能体协作等功能。
1433 91
|
11月前
|
开发框架 安全 JavaScript
文件上传漏洞(五)一句话合集
文件上传漏洞(五)一句话合集
|
11月前
|
存储 监控 BI
如何设置AD域用户仅登录到指定的计算机?AD域管理软件
本文介绍了如何使用AD域服务限制用户仅能登录特定计算机,包括通过属性设置和脚本实现。此外,提到了ADManagerPlus这款工具,它能够批量管理AD域用户,包括创建、修改用户信息,分配权限,并通过报表监控用户状态,有效提升AD域管理效率。
412 0
|
监控 数据挖掘
IEC104初学者教程,第九章:计数量召唤流程详解
在IEC 60870-5-104(简称IEC104)协议中,计数量召唤(Counter Interrogation,简称CI)是一种特定的功能,用于获取远程终端设备(RTU)中的计数值。这些计数值通常是累计数据,如电能表的累计电量等。计数量召唤流程与总召唤类似,但有其独特的步骤和信息结构。以下是计数量召唤的基本流程:
175 4
IEC104初学者教程,第九章:计数量召唤流程详解
|
9月前
|
存储 人工智能 JavaScript
【AI系统】公共表达式消除原理
公共子表达式消除(CSE)是编译器优化技术,旨在通过识别并消除重复计算的表达式,减少计算量,提升程序执行效率。CSE分为局部和全局两种,局部CSE仅在单个基本块内操作,而全局CSE跨越多个基本块。技术手段包括局部值编号和缓式代码移动等,广泛应用于传统编译器及AI编译器中,有效简化计算图,降低计算成本。
197 4
|
10月前
|
SQL 安全 网络协议
网络空间安全之一个WH的超前沿全栈技术深入学习之路(1-2):渗透测试行业术语扫盲)作者——LJS
网络空间安全之一个WH的超前沿全栈技术深入学习之路(1-2):渗透测试行业术语扫盲)作者——LJS
|
11月前
|
运维 自然语言处理 开发者
作为一名运维人员,使用通义灵码个人版处理日常工作中的代码相关任务,极大地提升了我的工作效率。以下是我使用通义灵码的具体实践场景、效果和心得,以及相应的截图。
作为一名运维人员,我使用通义灵码处理日常工作中的代码任务,效率提升了30%。通义灵码帮助我快速理解复杂代码、生成准确的代码注释,并能从自然语言生成代码示例,大幅减少了代码编写和理解的时间。
289 3
visualscope的使用方法
visualscope的使用方法
473 0
visualscope的使用方法
|
存储 Java 开发者
Java-数据结构(三)-List:ArrayList和LinkedList及其相关面试题
Java-数据结构(三)-List:ArrayList和LinkedList及其相关面试题
388 0

热门文章

最新文章