一、线程锁

保证多线程数据的一致性,对锁内的资源进行锁定,同一时间只能有一个线程来修改共享的数据
多个线程同时加了同一个锁对象时,先获取到锁的线程会继续运行,未获取到锁的线程会处于堵塞状态,直到前面的线程释放锁,重新获取到锁才会往下运行

类型

threading.Lock
基本锁对象,每次只能获取一次,其他锁请求需要等锁释放后才能获取
若想对同一线程多次锁,必须等前面的锁释放,否则会变成死锁 threading.RLock
可重入锁,同一个线程中可以多次获取,也可以多次释放,但是获取和释放的次数必须要一致

锁对象的方法

Lock.acquire(blocking=True, timeout=-1)
获取锁,获取成功返回 True,否则返回 False
blocking: 默认True,堵塞没有获取到锁的线程
timeout: blocking=True时,没有获取到锁的线程的堵塞超时时间,默认-1,无限制等待;blocking=Flase时,禁止设置timeout Lock.release()
释放锁,可以从任何线程调用此函数,没有返回值
对已解锁的锁使用该方法引发 RuntimeError 异常

示例

不加锁时

取钱两次之后,余额是负数

import threading, time

#账户类
class Account:
def __init__(self, account_no, balance):
#账户编号和账户余额
self.account_no = account_no
self.balance = balancedef getBlance(self):
return self.balance #提取现金方法
def draw(self, draw_amount):
if self.balance >= draw_amount:
print(threading.current_thread().name+'\t取钱成功!吐出钞票:'+str(draw_amount))
time.sleep(1)
self.balance -= draw_amount
print(threading.current_thread().name+'操作之后\t余额为:'+str(self.balance))
else:
print(threading.current_thread().name+'\t取钱失败!余额不足!\t当前余额为:'+str(self.balance)) acct = Account('986623', 1500)
thread_1 =threading.Thread(target=acct.draw, args=(800,), name='thread_1')
thread_2 =threading.Thread(target=acct.draw, args=(900,), name='thread_2')
thread_1.start()
thread_2.start()

加锁时

#账户类
class Account:
def __init__(self, account_no, balance):
#账户编号和账户余额
self.account_no = account_no
self.balance = balance self.lock = threading.RLock() def getBlance(self):
return self.balance #提取现金方法
def draw(self, draw_amount):
with self.lock:
if self.balance >= draw_amount:
print(threading.current_thread().name+'\t取钱成功!吐出钞票:'+str(draw_amount))
time.sleep(1)
self.balance -= draw_amount
print(threading.current_thread().name+'操作之后\t余额为:'+str(self.balance))
else:
print(threading.current_thread().name+'\t取钱失败!余额不足!\t当前余额为:'+str(self.balance)) acct = Account('986623', 1500)
thread_1 =threading.Thread(target=acct.draw, args=(800,), name='thread_1')
thread_2 =threading.Thread(target=acct.draw, args=(900,), name='thread_2')
thread_1.start()
thread_2.start()

死锁

当两个线程互相等待对方释放各自要加锁的锁对象时(即两个线程占用着各自将要加锁的锁对象),就会产生死锁
出现死锁时,程序会出现僵持的状态并且无法继续执行下去

避免死锁问题

避免多次锁定: 尽量避免同一个线程对多个锁对象进行锁定
具有相同的加锁顺序: 多个线程对多个锁对象加锁时,应该保证它们以相同的顺序请求加锁
使用定时锁: 程序在调用acquire()方法加锁时可以指定timeout参数,超时会自动释放锁
死锁检测: 依靠算法机制来实现的死锁预防机制

最新文章

  1. Maven(一)环境搭建
  2. nginx反向代理proxy模块相关参数
  3. 【阅读】提问的智慧+有效的报告BUG
  4. [ECNU 1624] 求交集多边形面积
  5. CSS Sprites的详细使用步骤
  6. Niagara技术文档汇总
  7. SpringMVC 学习笔记(两) @RequestMapping、@PathVariable和其他注意事项
  8. React 在服务端渲染的实现
  9. main方法和args参数
  10. Selenium+Python ---- 免登录、等待、unittest单元测试框架、PO模型
  11. java 集合框架(十)List
  12. LayoutInflater和inflate的用法,有图有真相
  13. React Native之配置开发环境
  14. mysql数据从windows导出,再导入到linux
  15. SkylineGlobe 如何实现二次开发加载KML文件
  16. Hadoop开发环境配置2-eclipse集成maven插件
  17. week05 06绑定滚动条 去抖动
  18. JavaScript动画:offset和匀速动画详解(含轮播图的实现)
  19. 【C++】atoi与stoi
  20. 类名.class和getClass()区别

热门文章

  1. 使用Telnet伪造邮件发送
  2. springboot ElasticsearchRepository date_histogram 聚合查询
  3. 【C++】【纯代码】获取电脑的mac地址
  4. Windows10使用WSL(Windows Subsystem for Linux)
  5. 12组-Beta冲刺-5/5
  6. sleep(0)的意义
  7. sxt_(001_002)_web简介
  8. Cgroup学习笔记3—代码实现—相关结构和全局变量
  9. windows远程桌面之前用于连接到xxx的凭据无法工作
  10. 如何下载zoom上别人录制的视频?