一、数据冲突
一般发生在多个线程对同一个数据进行操作的时候
注意: Queue对象本身就是线程安全的,不会出现数据冲突
举例:
from threading import Thread
data = 0
def up_data():
global data
for _ in range(100008):
data += 1
def down_data():
global data
for _ in range(100000):
data -= 1
if __name__ == '__main__':
# 情况1: 在一个线程中对同一个数据进行加和减的操作
# up_data()
# down_data()
# print(data)
# 情况2:在两个线程中进行加和减操作
t1 = Thread(target=up_data)
t2 = Thread(target=down_data)
t1.start()
t2.start()
t1.join()
t2.join()
print(data)
执行结果:
8
二、手动Lock
Lock - 锁类, 传统锁,重量级锁(加锁和解锁需要手动进行)
举例:
from threading import Thread, Lock
data = 0
# 1.创建锁对象(有多少个数据就创建多个锁)
data_lock = Lock()
def up_data():
global data
for _ in range(100008):
# 2.加锁
data_lock.acquire()
data += 1
# 3.解锁
data_lock.release()
def down_data():
global data
for _ in range(100000):
data_lock.acquire()
data -= 1
data_lock.release()
if __name__ == '__main__':
t1 = Thread(target=up_data)
t2 = Thread(target=down_data)
t1.start()
t2.start()
t1.join()
t2.join()
print(data)
执行结果:
8
三、自动锁RLock
举例:
from threading import Thread, RLock
data = 0
data_lock = RLock()
def up_data():
global data
for _ in range(100008):
# 使用锁(会自动加锁和解锁)
with data_lock:
data += 1
def down_data():
global data
for _ in range(100000):
with data_lock:
data -= 1
if __name__ == '__main__':
t1 = Thread(target=up_data)
t2 = Thread(target=down_data)
t1.start()
t2.start()
t1.join()
t2.join()
print(data)
执行结果:
8