锁简易知识讲解

编程入门 行业动态 更新时间:2024-10-09 02:25:03

锁<a href=https://www.elefans.com/category/jswz/34/1769136.html style=简易知识讲解"/>

锁简易知识讲解

系列文章目录

文章目录

  • 系列文章目录
  • 前言
  • 一、锁的分类?
  • 二、深入了解Lock接口
    • 1.lock与synchronized的区别
    • 2.实现属于自己的锁
    • 3.AbstractQueuedSynchronizer浅析
    • 4.如何阅读源码:
    • 5.深入剖析ReentrantLock源码之公平锁的实现
    • 6.读写锁特性以及ReentrantReadWriteLock的使用
    • 7.锁降级详解
    • 2.读入数据
  • 总结


前言

一、锁的分类?

自旋锁:线程状态及上下文切换消耗系统资源,当访问共享资源的时间短,频繁上下文切换不值得。jvm实现,使线程在没获得锁的时候,不被挂起,转而执行空循环,循环几次之后,如果还没能获得锁,则被挂起

阻塞锁:阻塞锁改变了线程的运行状态,让线程进入阻塞状态进行等待,当获得相应的信号(唤醒或者时间)时,才可以进入线程的准备就绪状态,转为就绪状态的所有线程,通过竞争,进入运行状态

重入锁:支持线程再次进入的锁,就跟我们有房间钥匙,可以多次进入房间类似。

读写锁:两把锁,读锁和写锁,写写互斥,读写互斥,读读共享。

互斥锁:上厕所,进门之后就把门关了,不让其他人进来。

悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞知道它拿到锁。

乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。

公平锁:大家都老老实实排队,对大家而言都很公平。

非公平锁:一部分人排着队,但是新来的可能插队

偏向锁:偏向锁使用了一种等到竞争出现才释放锁的机制,所以当其他线程尝试竞争偏向锁时,持有偏向锁的线程才会释放锁

独占锁:独占锁模式下,每次只能有一个线程能持有锁

共享锁:允许多个线程同时获得锁,并发访问共享资源

二、深入了解Lock接口

1.lock与synchronized的区别

lock:获取锁与释放锁的过程,都需要程序员手动的控制,lock用的是乐观锁方式(所谓乐观锁就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止,乐观锁实现的机制就是CAS操作)

synchronized:托管给jvm执行,原始采用的是CPU悲观锁机制,及线程获得是独占锁(独占锁意味着其他线程只能依靠阻塞来等待线程释放锁),实现lock接口的锁哥哥各个方法的简介

2.实现属于自己的锁

实现lock接口
使用wait notify

3.AbstractQueuedSynchronizer浅析

AbstractQueuedSynchronizer – 为实现依赖于先进先出(FIFO)等待队列的阻塞锁和相关同步器(信号量,事件,等等)提供一个框架。

此类的设计目标是成为依靠单个原子int值来表示状态的大多数同步器的一个有用基础。

子类必须定义更改此状态的受保护方法,并定义哪种状态对于此对象意味着被获取或被释放。

假定这些条件之后。此类中的其他方法就可以实现所有排队和阻塞机制。

子类可以维护其他状态字段,但只是为了获得同步而只追踪使用getState(),setState(int)和compareAndSestate(int,int)方法来操作以原子方式更新的int值。

应该将子类定义为非公共内部帮助类,可用他们来实现其封闭类的同步属性,类AbstractQueuedSynchronizer 没有实现任何同步接口,而是定义了诸如acquireInterruptibly(int)之类的一些方法,在适当的时候可以通过具体的锁和相关同步器来调用他们,以实现其公共方法。

此类支持默认的独占模式和共享模式之一,或者二者都支持。处于独占模式下时,其他线程试图获取该锁将无法取得成功

在共享模式下,多个线程获取某个锁可能(但不是一定)会获得成功。此类并不“了解”这些不同,除了机械地意识到当在共享模式下成功获取某一锁时,下一个等待线程(如果存在)也必须确定自己是否可以成功获取该锁。处于不同模式下的等待线程可以共享相同的FIFO队列。通常子类只支持一种模式,但两种模式都可以在(例如)ReadWriteLock中发挥作用。只支持独占模式或者只支持共享模式的子类不必定义支持未使用模式的方法

此类通过支持独占模式的子类定义了一个嵌套的 AbstractQueuedSynchronizer.ConditionObject 类,可以将这个类用作 Condition 实现。isHeldExclusively() 方法将报告同步对于当前线程是否是独占的;使用当前 getState() 值调用 release(int) 方法则可以完全释放此对象;如果给定保存的状态值,那么 acquire(int) 方法可以将此对象最终恢复为它以前获取的状态。没有别的 AbstractQueuedSynchronizer 方法创建这样的条件,因此,如果无法满足此约束,则不要使用它。AbstractQueuedSynchronizer.ConditionObject 的行为当然取决于其同步器实现的语义。

此类为内部队列提供了检查、检测和监视方法,还为 condition 对象提供了类似方法。可以根据需要使用用于其同步机制的 AbstractQueuedSynchronizer 将这些方法导出到类中。

此类的序列化只存储维护状态的基础原子整数,因此已序列化的对象拥有空的线程队列。需要可序列化的典型子类将定义一个 readObject 方法,该方法在反序列化时将此对象恢复到某个已知初始状态。

4.如何阅读源码:

一段简单的代码,看构造,看类之间的关系,形成关系图,看使用到的方法,并逐步理解,边看代码边看注释,debug一下

5.深入剖析ReentrantLock源码之公平锁的实现

公平锁:大家老老实实排队
非公平锁:只要有机会,就先尝试抢占资源
公平锁与非公平锁的区别:公平锁与非公平锁就像排队,公平锁遵守排队的规则,只要前面有人排队,那么刚进来的就老老实实排队,而非公平锁只要有空隙就进,不管后面的人排的是否辛苦。

非公平锁的弊端:可能导致后面排队等待的线程等不到相应的cpu资源,从而引起线程饥饿
`

6.读写锁特性以及ReentrantReadWriteLock的使用

特性:写写互斥,读写互斥,读读共享
锁降级:写线程获取写入锁后可以获取读取锁,然后释放写入锁,这样就从写入锁变成了读取锁,从而实现锁降级的特性。

7.锁降级详解

锁降级:写线程获取写入锁后可以获取读取锁,然后释放写入锁,这样就从写入锁变成了读取锁,从而实现了锁降级的特性。

注意点:锁降级之后,写锁并不会直接降级成读锁,不会随着读锁的释放而释放,因此需要显式地释放写锁

是否有锁升级:在ReentranReadWriteLock里面,不存在锁升级这一说法

锁降级的应用场景:用于对数据比较敏感,需要在对数据修改之后,获取到修改后的值,并进行接下来的其他操作

代码如下(示例):

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import  ssl
ssl._create_default_https_context = ssl._create_unverified_context

2.读入数据

代码如下(示例):

data = pd.read_csv('.data.csv')
print(data.head())

该处使用的url网络请求的数据。


总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

更多推荐

锁简易知识讲解

本文发布于:2024-02-27 20:35:50,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1766615.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:简易   知识

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!