锁、threading.local、线程池
一、锁
Lock(1次放1个)
什么时候用到锁:
线程安全,多线程操作时,内部会让所有线程排队处理。如:list、dict、queue
线程不安全,
import threading import time v = [] lock = threading.Lock() #实例化了一个对象****** def func(arg):lock.acquire() #加锁 v.append(arg)time.sleep(0.5)m = v[-1]print(arg,m)lock.release() #加锁就要有解锁对应 for i in range(1,11):t = threading.Thread(target=func,args=(i,))t.start()
RLock(1次放1个)
与Lock用法一致,但是RLock可以锁多次(必须有响应的解锁次数),Lock只能锁一次
import threading import time v = [] lock = threading.RLock() def func(arg):lock.acquire() #锁了两次lock.acquire()v.append(arg)time.sleep(0.1)m = v[-1]print(arg,m)lock.release() #解锁两次lock.release()for i in range(1,11):t = threading.Thread(target=func,args=(i,))t.start()
BoundedSemaphore(1次方固定个数个)
import time import threading lock = threading.BoundedSemaphore(3) #参数是多少就一次放过去多少个线程 def func(arg):lock.acquire()print(arg)time.sleep(1)lock.release() for i in range(1,11):t = threading.Thread(target=func,args=(i,))t.start()
Condition(1次放N个)
import time import threading lock = threading.Condition() def func(arg):print("start")lock.acquire()lock.wait() #****print(arg)time.sleep(1)lock.release() for i in range(1,11):t = threading.Thread(target=func,args=(i,))t.start() while 1:num = int(input(">>>>>")) #输入多少本次就会放多少个线程lock.acquire() #**** lock.notify(num)lock.release() #****
#也可以通过函数逻辑判断的返回值 def xx():print("来执行函数了")input(">>>>")return True def func(arg):print("线程来了")lock.wait_for(xx)print(arg)time.sleep(1) for i in range(1,11):t = threading.Thread(target=func,args=(i,))t.start()
Event(1次放所有)
import threading lock = threading.Event() def func(arg):print("线程来了")lock.wait()#加锁print(arg) for i in range(1,11):t = threading.Thread(target=func,args=(i,))t.start() input(">>>>") lock.set() #解锁,如果后面不加锁上面的wait就失效了 input(">>>>") lock.clear() #再次上锁 for i in range(1,11):t = threading.Thread(target=func,args=(i,))t.start() input(">>>>") lock.set()
总结:
线程安全,列表和字典线程安全
为什么要加锁:
非线程安全
控制一段代码
二、threading.local
作用:
内部自动为每个线程维护一个空间(字典),用于当前存取属于自己的值。保证线程之间的数据隔离
{
线程id:{......}
线程id:{......}
线程id:{......}
}
import time import threading v = threading.local() def func(arg):# 内部会为当前线程创建一个空间用于存储:phone=自己的值v.phone = argtime.sleep(1)print(v.phone,arg) # 去当前线程自己空间取值 for i in range(1,11):t = threading.Thread(target=func,args=(i,))t.start()
import time import threadingDATA_DICT = {}def func(arg):ident = threading.get_ident()DATA_DICT[ident] = argtime.sleep(1)print(DATA_DICT[ident],arg)for i in range(10):t =threading.Thread(target=func,args=(i,))t.start()
threading.local原理
import time import threading INFO = {} class Local(object):def __getattr__(self, item):ident = threading.get_ident()return INFO[ident][item]def __setattr__(self, key, value):ident = threading.get_ident()if ident in INFO:INFO[ident][key] = valueelse:INFO[ident] = {key:value} obj = Local() def func(arg):obj.phone = arg #对象.xx="xxx" 调用了__setattr__方法time.sleep(1)print(obj.phone,arg) #对象.xx 调用了__getattr__方法 for i in range(1,11):t = threading.Thread(target=func,args=(i,))t.start()
threading.local原理升级版
三、线程池
from concurrent.futures import ThreadPoolExecutor import time def func(a1,a2):time.sleep(1)print(a1,a2) #创建了一个线程池(最多5个线程) pool = ThreadPoolExecutor(5) for i in range(1,21): #去线程池中申请一个线程pool.submit(func,i,"a")
四、生产者消费者模型
三部件:
生产者
队列,先进先出
栈,后进先出
消费者
生产者消费者模型解决了什么问题:不用一直等待的问题
import time import threading import queue q = queue.Queue()#线程安全 def producer(id):while 1:time.sleep(2)q.put("包子")print("厨师%s生产了一个包子"%id) for i in range(1,3):t = threading.Thread(target=producer,args=(i,))t.start() def consumer(id):while 1:time.sleep(1)q.get("包子")print("顾客%s吃了一个包子"%id) for i in range(1,4):t = threading.Thread(target=consumer,args=(i,))t.start()
示例
转载于:https://www.cnblogs.com/qq849784670/p/9628841.html
锁、threading.local、线程池相关推荐
- 锁, threading.local, 线程池, 生产者消费者模型
一. 锁:Lock (1次放1个) 线程安全,多线程操作时,内部会让所有线程排队处理.如:list/dict/Queue 线程不安全 + 人 => 排队处理. 需求: a ...
- 蚂蚁三面题目(java开发岗):Java锁机制+JVM+线程池+事务+中间件
一面 1.HashMap底层原理?HashTable和ConcurrentHashMap他们之间的相同点和不同点? 2.由上题提到锁的问题 3.MySQL的表锁&行锁&乐观锁& ...
- java 资源锁_concurrent包 线程池、资源封锁和队列、ReentrantReadWriteLock介绍
jdk1.5后,提供了java.util.concurrent包,它可以实现线程池,你把线程当成普通对象就可以了,它来负责调度和执行 包括两类线程池 固定线程池 可变线程池 延迟线程池 固定线程池 p ...
- 线程的创建 锁 Threading模块 事件 条件 定时器 队列 线程池 回调函数
线程的创建: 创建线程的方式1: from threading import Thread import time def sayhi(name):time.sleep(2)print('%s say ...
- java 变量锁_并发编程高频面试题:可重入锁+线程池+内存模型等(含答案)
对于一个Java程序员而言,能否熟练掌握并发编程是判断他优秀与否的重要标准之一.因为并发编程是Java语言中最为晦涩的知识点,它涉及操作系统.内存.CPU.编程语言等多方面的基础能力,更为考验一个程序 ...
- java架构学习——5. 线程池原理剖析锁的深度化
本篇博文主要包含: 线程池的基本概念 ThreadPoolExecutor 线程池四种创建方式 -newCachedThreadPool:可缓存线程池 -newFixedThreadPool:定长线程 ...
- 线程队列 线程池 协程
1 . 线程队列 from multiprocessing Queue , JoinableQueue #进程IPC队列 from queue import Queue #线程队列 先进先出 f ...
- python线程池原理_Django异步任务线程池实现原理
这篇文章主要介绍了Django异步任务线程池实现原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 当数据库数据量很大时(百万级),许多批量数据修改 ...
- 深入了解java线程池
在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统 ...
- Java并发编程:线程池
一.为什么使用线程池 使用线程的时候直接就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降 ...
最新文章
- NXT节点搭建(二)环境搭建
- boost shared_ptr线程安全性
- C# 控件双缓冲控制 ControlStyles 枚举详解
- java单例设计模式_Java设计模式之单例模式详解
- php网站开发项目实战,PHP动态网站开发项目实战
- sklearn 常用模块及类与方法
- Nginx使用教程(八):使用Nginx缓存之Memcached缓存
- spring mvc静态资源放行
- Dorado7自定义下拉框
- Supporting hyperplane
- 求和符号的定义和性质
- html如何让table表格垂直(上下)居中
- 雨林木风 Ghost XP SP2 精简版 Y2.0
- The Fool HDU - 6555
- 因为计算机中丢失slimage,slimage.dll
- 算法提高 质数的后代
- django+xadmin学习笔记
- 欧拉操作系统(openEuler)简介
- 面试遇到原题时,“演员”的自我修养
- LED学习及一个花样流水灯的实现
热门文章
- 1092 最好吃的月饼 (20 point(s))- PAT乙级真题
- [Java] 蓝桥杯ADV-175 算法提高 三个整数的排序
- PAT 乙级 1031. 查验身份证(15) Java版
- ALGO-146算法训练 4-2找公倍数
- 运行vue init webpack vueTest时报错
- [Python]学习基础篇:面向对象编程
- 中国人工智能学会通讯——基于视频的行为识别技术 1.5 基于深度学习的视频识别方法...
- Go语言栈定义及相关方法实现
- linux(CentOS)下Mrtg的安装詳解
- 查询数据表中重复记录