什么是线程锁和进程锁?什么是死锁,死锁产生的原因和解决锁的办法
线程锁:当多个线程几乎同时修改一个共享数据的时候,需要进行同步控制,线程同步能够保证多个线程安全的访问竞争资源(全局内容),最简单的同步机制就是使用互斥锁。
某个线程要更改共享数据时,先将其锁定,此时资源的状态为锁定状态,其他线程就能更改,直到该线程将资源状态改为非锁定状态,也就是释放资源,其他的线程才能再次锁定资源。互斥锁保证了每一次只有一个线程进入写入操作。从而保证了多线程下数据的安全性。
进程锁:也是为了控制同一操作系统中多个进程访问一个共享资源,只是因为程序的独立性,各个进程是无法控制其他进程对资源的访问的,但是可以使用本地系统的信号量控制。
死锁:在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待状态。
当线程进入对象的synchronized代码块时,便占有了资源,直到它退出该代码块或者调用wait方法,才释放资源,在此期间,其他线程将不能进入该代码块。当线程互相持有对方所需要的资源时,会互相等待对方释放资源,如果线程都不主动释放所占有的资源,将产生死锁。
当然死锁的产生是必须要满足一些特定条件的:
互斥条件:进程对于所分配到的资源具有排它性,即资源不能被共享,只能由一个进程使用(一个资源只能被一个进程占用,直到被该进程释放 。)
请求和保持条件:一个进程因请求被占用资源而发生阻塞时,对已获得的资源保持不放。
非剥夺条件:任何一个资源在没被该进程释放之前,任何其进程都无法对他剥夺占用。
循环等待条件:当发生死锁时,所等待的进程必定会形成一个环路(类似于死循环),造成永久阻塞。
递归死锁:在多线程的环境下使用递归,遇到了多线程那么就不得不面对同步的问题。而递归程序遇到同步的时候很容易出问题。
多线程的递归就是指递归链中的某个方法由另外一个线程来操作。
解决死锁的办法有:
按同一顺序访问对象。(注:避免出现循环)
避免事务中的用户交互。(注:减少持有资源的时间,较少锁竞争)
保持事务简短并处于一个批处理中。(注:同(2),减少持有资源的时间)
使用较低的隔离级别。(注:使用较低的隔离级别(例如已提交读)比使用较高的隔离级别(例如可序列化)持有共享锁的时间更短,减少锁竞争)
尽量减少资源占用的时间,可以降低死锁的发生的概率
银行家算法。
要想说银行家,首先得说死锁问题,因为银行家算法就是为了死锁避免提出的。那么,什么是死锁?简单的举个例子:俩人吃饺子,一个人手里拿着酱油,一个人手里拿着醋,拿酱油的对拿着醋的人说:“你把醋给我,我就把酱油给你”;拿醋的对拿着酱油的人说:“不,你把酱油给我,我把醋给你。”
于是,俩人这两份调料是永远吃不上了。这就是死锁。
那么,为啥这个算法叫银行家算法?因为这个算法同样可以用于银行的贷款业务。让我们考虑下面的情况。
一个银行家共有20亿财产
第一个开发商:已贷款15亿,资金紧张还需3亿。
第二个开发商:已贷款5亿,运转良好能收回。
第三个开发商:欲贷款18亿在这种情况下,如果你是银行家,你怎么处理这种情况?一个常规的想法就是先等着第二个开发商把钱收回来,然后手里有了5个亿,再把3个亿贷款给第一个开发商,等第一个开发商收回来18个亿,然后再把钱贷款给第三个开发商。
这里面什么值得学习呢?最重要的就是眼光放长一点,不要只看着手里有多少钱,同时要注意到别人欠自己的钱怎么能收回来。那么正经点说这个问题,第一个例子中:醋和酱油是资源,这俩吃饺子的是进程;第二个例子中:银行家是资源,开发商是进程。在操作系统中,有内存,硬盘等等资源被众多进程渴求着,那么这些资源怎么分配给他们才能避免“银行家破产”的风险?
银行家算法----安全序列
安全序列是指对当前申请资源的进程排出一个序列,保证按照这个序列分配资源完成进程,不会发生“酱油和醋”的尴尬问题。
Available = [] #各可用资源数目
Used ={} #某进程目前占有各资源数
Need = {} #某进程目前需求资源数
zhan = [] #临时存储列表
order = [] #进程安全顺序列表
pandaun = []
def compare(a = [],b = []):for x in range(0,item): #进行列表对应元素的比较if (int(a[x]) < int(b[x])): #一旦出现供不应求的情况即返回Falsereturn Falsebreak #且跳出循环return True #如果符合条件即返回True
def AddUsed(a = [],b = []): #可用资源某进程当前占用资源对应位置相加for x in range(0,item): a[x] = int(a[x]) + int(b[x])
item = int(input("请输入资源种类数: "))
SP = int(input("请输入进程数: "))
jinchengshu = SP #设置临时变量表示进程数量,在后面的判断中用
#输入各类资源的可用数目并存储到列表Available中
for x in range(1,item+1):Available.append(input("请输入第"+str(x)+"种资源的可用数目: "))
#输入各进程名称,占有资源数及所需,键值对存储
for x in range(1,SP+1):name = input("请输入第"+str(x)+"个进程名称: ")print("该进程占有的"+str(item)+"类资源数为:")for y in range(1,item+1):zhan.append(int(input()))Used[name] = zhanzhan = [] #清空临时列表print("该进程需要的"+str(item)+"类资源数为:") for z in range(1,item+1):zhan.append(int(input()))Need[name] = zhanzhan = [] #清空临时列表
#安全性算法开始
while Need: #如果进程表Need不为空for key in Need: #获取Need中的keyzhan = Need[key] #将对应的value赋值给临时列表zhanif compare(Available,zhan):#调用比较函数比较列表中个元素与Avilable中个元素的大小并返回真值AddUsed(Available,Used[key]) #如果返回True则调用相加函数order.append(key) #将key值放入order列表中以便显示a = key #设置a令它等于key,删除字典元素时使用breakif compare(Available,zhan): #如果符合大小条件就删除对应的键值对del Need[a]jinchengshu -= 1if SP == jinchengshu:print("不存在安全序列!!!")break
if jinchengshu == 0:for x in range(0,len(order)):print(order[x]+'-->',end='')print("END!")
什么是线程锁和进程锁?什么是死锁,死锁产生的原因和解决锁的办法相关推荐
- 分布式锁,进程锁,线程锁到底是什么
在分布式集群系统的开发中,线程锁往往并不能支持全部场景的使用,必须引入新的技术方案分布式锁. 线程锁:大家都不陌生,主要用来给方法.代码块加锁.当某个方法或者代码块使用锁时,那么在同一时刻至多仅有有一 ...
- 一句话说清分布式锁,进程锁,线程锁
一句话说清分布式锁,进程锁,线程锁 在分布式集群系统的开发中,线程锁往往并不能支持全部场景的使用,必须引入新的技术方案分布式锁. 线程锁,进程锁,分布式锁 线程锁:大家都不陌生,主要用来给方法.代码块 ...
- 正在等待缓存锁:无法获得锁_一句话说清分布式锁,进程锁,线程锁
推荐阅读 1. Java 性能优化:教你提高代码运行的效率 2. Java问题排查工具清单 3. 记住:永远不要在MySQL中使用UTF-8 4. Springboot启动原理解析 在分布式集群系统的 ...
- 详解线程锁、进程锁、分布式锁以及数据库锁
线程锁.进程锁.分布式锁以及数据库锁 1. 锁的介绍以及应用: 2. 定时器实现任务生产: 3. 手撕多线程任务队列: 视频讲解如下,点击观看: 线程锁.进程锁.分布式锁以及数据库锁丨C/C++丨Li ...
- 详解线程锁、进程锁以及分布式锁,开发过程中解决的具体问题
聊聊线程锁.进程锁以及分布式锁 1. 线程锁-如何调度消费任务队列的线程池: 2. 进程锁-如何解决nginx惊群问题 3. 分布式锁-如何解决分布式系统中锁竞争问题 [Linux后端开发系列]详解线 ...
- 线程锁,进程锁以及分布式锁丨锁的实现及原理分析丨高效的使用
线程锁.进程锁以及分布式锁 1. 线程锁 2. 进程锁 3. 分布式锁 [技术分享篇]线程锁,进程锁以及分布式锁丨锁的实现及原理分析丨高效的使用 更多精彩内容包括:C/C++,Linux,Nginx, ...
- 到底什么是分布式锁,进程锁,线程锁
在分布式集群系统的开发中,线程锁往往并不能支持全部场景的使用,必须引入新的技术方案分布式锁. 线程锁 主要用来给方法.代码块加锁.当某个方法或者代码块使用锁时,那么在同一时刻至多仅有有一个线程在执行该 ...
- oracle 查看锁表进程和解锁
查看锁表进程和解锁 (1)方式一: SELECT SESS.SID, SESS.SERIAL#, LO.ORACLE_USERNAME, ...
- oracle查看锁表进程,杀掉锁表进程
查看锁表进程SQL语句1: select sess.sid, sess.serial#, lo.oracle_username, lo.os_user_name, ao.object_name, lo ...
最新文章
- 1、orcal database 11g体系机构概述
- Docker(十四):Docker:网络模式详解
- spark数据查询语句select_sparksql语句
- linux 自学系列:用户管理
- Project Eular 634
- 金蝶结账时显示系统错误h80004005_金蝶KIS云专业版(仓存模块)常见问题解决汇总...
- 我的asp.net学习心得
- [递推] hihocoder 1239 Fibonacci
- 34个省市自治区排序_freeCodeCamp的1,000多个学习小组现已完全自治
- class触发后让另一个class加样式_Bootstrap的按钮组样式
- Android系统(转)
- php serv-u,用php写的serv-u的web申请账号的程序_php
- JAVA生成条码(jbarcode)
- 181219每日一句
- 毕业设计系列1--基于ESP8266设计智能插座--材料清单
- 在线硬盘存储计算机,【模拟攒机-模拟装机】在线攒电脑-ZOL中关村在线
- Sensor Flicker (Sensor banding现象)
- CSS Font-awesome字体图标库文件
- 猪猪侠的黑客学习路线
- iPhone问世15周年,共33款机型,你用过哪几个?