并发编程—创建多线程的三种方式

#!/usr/local/bin/python3
"""
多线程程序如果没有竞争资源的场景那么通常会比较简单
临界资源 - 被多个线程竞争的资源
当多个线程竞争临界资源的时候如果缺乏必要的保护措施就会导致数据错乱
"""
import time
import threading

from concurrent.futures import ThreadPoolExecutor


class Account(object):
    """银行账户"""

    def __init__(self):
        self.balance = 0.0
        self.lock = threading.Lock()

    def deposit(self, money):
        # 通过锁保护临界资源
        # 可以写try-finally也可以使用上下文语法
        # self.lock.acquire()
        # try:
        #     pass
        # finally:
        #     self.lock.release()
        with self.lock:
            new_balance = self.balance + money
            time.sleep(0.001)
            self.balance = new_balance


def add_money(account, money):
    account.deposit(money)


# 自定义线程类
class AddMoneyThread(threading.Thread):

    def __init__(self, account, money):
        self.account = account
        self.money = money
        # 自定义线程的初始化方法中必须调用父类的初始化方法
        super().__init__()

    # run方法是线程启动之后要执行的回调方法(钩子函数)
    # 所以启动线程不能够直接调用run方法而是通过start方法启动线程
    # 什么时候需要使用回调式编程?
    # 你知道要做什么但不知道什么时候会做这件事情
    def run(self):
        # 线程启动之后要执行的操作
        pass

def main():
    account = Account()
    # 创建线程池
    pool = ThreadPoolExecutor(max_workers=10)
    futures = []
    for _ in range(100):
        # 创建线程的第1种方式
        # threading.Thread(
        #     target=add_money, args=(account, 1)
        # ).start()
        # 创建线程的第2种方式
        # AddMoneyThread(account, 1).start()
        # 创建线程的第3种方式
        # 调用线程池中的线程来执行特定的任务
        future = pool.submit(add_money, account, 1)
        futures.append(future)
    # 关闭线程池
    pool.shutdown()
    for future in futures:
        future.result()
    print(account.balance)


if __name__ == '__main__':
    main()

你可能感兴趣的:(并发编程—创建多线程的三种方式)