有序打印:
给定一个类
class Foo():
def first():
print("first", end=" ")
def second():
print("second", end=" ")
def third():
print("third", end=" ")
建立实例化对象,建立3个线程,此时3个线程都共享这个对象,
让3个线程分别运行 first(), second(), third(), 需要确保 first second third 的打印顺序
方法一;
线程锁
一个线程在代码的某处使用线程锁后(acquire),在这个锁释放前(release),其它线程都不能再使用这个锁。
场景一:用线程锁,包含某段代码,这样每次就只会有一个线程执行这段代码
场景二:在代码A处使用了线程锁 lock1,在代码B处也使用了 lock1。
假设线程 t1 先执行到代码A处(lock1开启了), 在代码块还没执行完时(lock1还未释放),
线程 t2 执行到代码B处,此时就会请求开启 lock1, 但由于 lock1在线程t1还未释放,
由此线程t2就会阻塞在这里,等待线程t1释放 lock1
此题类似场景二, 打印 first 和 second 处可以使用相同的线程锁,这样就可以确保在打印完一个后才能打印另外一个。
因此问题转变成 “怎么让打印first的线程,第一个获取线程锁?”,
可以换一个思路 “在所有线程运行前,就开启线程锁,在打印完first后,才释放这个锁” 这样即使打印 second 的线程
先运行,由于线程锁还未释放,不会重新开启锁,也就不会先打印 second
from threading import Lock, Thread
class Foo:
def __init__(self):
self.first_lock = Lock()
self.second_lock = Lock()
self.first_lock.acquire()
self.second_lock.acquire()
def first(self, print_first: 'Callable[[], None]') -> None:
# printFirst() outputs "first".
print_first()
# Notify the thread that is waiting for the first job to be done.
self.first_lock.release()
def second(self, print_second: 'Callable[[], None]') -> None:
# Wait for the first job to be done
self.first_lock.acquire()
# print_second() outputs "second".
print_second()
# Notify the thread that is waiting for the second job to be done.
self.second_lock.release()
self.first_lock.release()
def third(self, print_third: 'Callable[[], None]') -> None:
# Wait for the second job to be done.
with self.second_lock:
# print_third() outputs "third".
print_third()
def print_first():
print("first", end=" ")
def print_second():
print("second", end=" ")
def print_third():
print("third", end=" ")
if __name__ == '__main__':
foo = Foo()
t1 = Thread(target=foo.first, args=[print_first])
t2 = Thread(target=foo.second, args=[print_second])
t3 = Thread(target=foo.third, args=[print_third])
t3.start()
t2.start()
t1.start()