线程锁的作用: 当多个线程同时进行任务时,为保证不会有多个线程对同一个数据进行操作造成不可预料的后果,加个锁,将此时的线 程变为单线程进行操作。
当多个线程同时执行lock.acquire时,只有一个线程能成功地获取锁,然后继续执行代码,其他线程就继续等待直到获得 锁为止。 获得锁的线程用完后一定要释放锁,否则那些苦苦等待锁的线程将永远等待下去,成为死线程。
线程锁的好处与坏处:
好处:确保了某一段断码只能有一个线程从头到尾完整的执行。
坏处:首先是阻止了多线程的多发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大的降低。
其次由于可以存在多个锁,不同线程存在不同的锁,并试图获取对方持有的锁时,可能会造成锁死,导致多个 线程全部挂起,既不能执行也不能结束,只能靠操作系统强制终止。
方法一:
实例化对象方式—实现线程同步之线程锁
1.实例化一个锁对象;
lock=threading.Lock()
2.操作变量之前进行加锁
lock.acquire()
3.操作变量之后进行解锁
lock.release()
示例:
#money这个数据就是一个全局变量,当线程要对其进行操作时,就必须应用到线程锁。
import threading
# 银行存钱和取钱
def add(lock):
global money # 生命money为全局变量
for i in range(1000000):
# 2. 操作变量之前进行加锁
lock.acquire()
money += 1 # money; money+1; money=money+1;
# 3. 操作变量之后进行解锁
lock.release()
def reduce(lock):
global money
for i in range(1000000):
# 2. 操作变量之前进行加锁
lock.acquire()
money -= 1
# 3. 操作变量之后进行解锁
lock.release()
if __name__ == '__main__':
money = 0
# 1. 实例化一个锁对象;
lock = threading.Lock()
t1 = threading.Thread(target=add, args=(lock,))
t2 = threading.Thread(target=reduce, args=(lock,))
t1.start()
t2.start()
t1.join()
t2.join()
print("当前金额:", money)
方法二
继承方式—实现线程同步之线程锁
1. 实例化一个锁对象;
lock = threading.Lock()
2. 操作变量之前进行加锁
lock.acquire()
3. 操作变量之后进行解锁
lock.release()
示例:
import threading
class AddThread(threading.Thread):
def __init__(self, lock):
super(AddThread, self).__init__()
self.lock = lock
def run(self):
for i in range(1000000):
# 2. 操作变量之前进行加锁
self.lock.acquire()
global money
money += 1 # money; money+1; money=money+1;
# 3. 操作变量之后进行解锁
self.lock.release()
class ReduceThread(threading.Thread):
def __init__(self, lock):
super(ReduceThread, self).__init__()
self.lock = lock
def run(self):
global money
for i in range(1000000):
# 2. 操作变量之前进行加锁
lock.acquire()
money -= 1
# 3. 操作变量之后进行解锁
lock.release()
if __name__ == '__main__':
money = 0
# 1. 实例化一个锁对象;
lock = threading.Lock()
t1 = AddThread(lock)
t2 = ReduceThread(lock)
t1.start()
t2.start()
t1.join()
t2.join()
print("当前金额:", money)