经典多线程题目【交替打印】之 Python 3 解法
昨晚葛优躺刷手机时看到某Java大神讲解经典面试题“交替打印”,饶有兴趣的看了一下。可惜啊,本人是Java 学渣,主要用的开发语言是Python。看完之后,自己也陷入空顿中,Python 3 中如何实现呢?
结果就有了这篇文章。
题目
用两个线程实现交替打印字母和数字,最终的效果应为 A 0 B 1 C 2 …
这里就不说 Java 怎么搞了啊,直接说 Python。
第一个想到的是用 threading.Condition,没到自己打印时候就 wait(),打印完了就设置 flag 并 notify()。
题解
大家都很忙,话不多说,直接上代码。Condition 不太了解的直接网上查吧,很多资料。
我把实现更拓展了一下,N个交替打印都可以。题目中是 大写字母、小写字母和数字。
以下代码在 Python 3.7 亲测可用。
import threading
from functools import wraps
from string import ascii_uppercase, ascii_lowercase
COND = threading.Condition()
PRINT_ORDER = ['U', 'L', 'N']
FLAG = PRINT_ORDER[0]
def validate(func):
@wraps(func)
def valid_value(self, length, p_type, *args, **kwargs):
if length < 2 or length > 26:
raise ValueError("Length must value in [2, 26].")
if p_type not in PRINT_ORDER:
raise ValueError(f"p_type must be one of {PRINT_ORDER}!")
return func(self, length, p_type, *args, **kwargs)
return valid_value
class Print(threading.Thread):
@validate
def __init__(self, length: int, p_type: str, thread_name=None, *args, **kwargs):
super(Print, self).__init__(name=thread_name, *args, **kwargs)
self.length = length
self.type = p_type
self.next_action = PRINT_ORDER[(PRINT_ORDER.index(self.type) + 1) % len(PRINT_ORDER)]
self.index = 0
def __get_print_value(self):
if self.index > self.length - 1:
return None
if self.type == 'U':
return ascii_uppercase[self.index]
elif self.type == 'L':
return ascii_lowercase[self.index]
else:
return str(self.index)
def run(self) -> None:
print_value = self.__get_print_value()
global FLAG
while print_value is not None:
with COND:
if FLAG != self.type:
COND.wait()
else:
print(print_value, end=' ')
self.index += 1
print_value = self.__get_print_value()
FLAG = self.next_action
COND.notify_all()
def cross_print(count: int):
t1 = Print(length=count, p_type='U')
t1.start()
t2 = Print(length=count, p_type='L')
t2.start()
t3 = Print(length=count, p_type='N')
t3.start()
if __name__ == '__main__':
cross_print(15)