线程(下)

线程(下)

一、队列

1.1先进先出

import queue  #导入队列模块

q = queue.Queue(3)  #实例化一个队列对象,允许在里面放入3个数据
q.put(123)
q.put('you are my sunshine')
q.put([1,2,3,4])

print(q.get())
print(q.get())
print(q.get())

'''
123
you are my sunshine
[1, 2, 3, 4]
'''

1.2先进后出(堆栈)

q = queue.LifoQueue()   #实例化一个队列,这个队列的原则是先进后出
q.put(123)
q.put('you are my sunshine')
q.put([1,2,3,4])

print(q.get())
print(q.get())
print(q.get())

'''
[1, 2, 3, 4]
you are my sunshine
123
'''

1.3 按优先级进出

q= queue.PriorityQueue(3)  #实例化一个优先级输出数据的队列的对象
q.put((1,'emmm'))   #括号里面是一个元祖,通常这个元祖的第一个值是int类型
q.put((2,'emmm'))
q.put((3,'emmm'))

print(q.get())  #(1, 'emmm')  先输出优先级高的


q= queue.PriorityQueue(3)
q.put((1,'emmm'))   #括号里面是一个元祖
q.put((1,'aaaa'))
q.put((3,'emmm'))

print(q.get())  #(1, 'aaaa')   当前面的数字一样时,后面的字符串是按照Ascall码排

二、定时器

import time
from threading import Thread,Timer

def task():
    print('线程开始')
    time.sleep(1.5)
    print('线程结束')

t = Timer(3,task)   #3秒之后开启一个线程,也就是说3秒之后打印出来了子线程中的内容
t.start()

三、线程池与进程池

​ 池的功能是限制进程数或线程数,当并发的任务数远远大于计算机所能承受的范围,即无法开启过多的任务数,我们就应该考虑限制进程数或者线程数,从而保证服务器不崩。

3.1 线程池

from concurrent.futures import ThreadPoolExecutor
from threading import currentThread
import time

def task(i):
    time.sleep(1.5)
    print(f"{currentThread().name}在执行任务{i+1}")
    return i**2

if __name__ == '__main__':
    fu_list = []
    pool = ThreadPoolExecutor(4)  #规定线程池有是个线程
    for i in range(20):  #模拟20个线程,task要做20次,4个线程负责做这个事情
        future = pool.submit(task,i)   #for循环一次,提交一次
        fu_list.append(future)   #先把提交的数据意义放到这个列表里面
    pool.shutdown()   # 关闭池的入口,不让你往里面再放东西
    for fu in fu_list:  #依次循环列表里面的值
        print(fu.result())  #打印返回值

'''
ThreadPoolExecutor-0_1在执行任务2
ThreadPoolExecutor-0_0在执行任务1
ThreadPoolExecutor-0_3在执行任务4
ThreadPoolExecutor-0_2在执行任务3

ThreadPoolExecutor-0_1在执行任务6
ThreadPoolExecutor-0_0在执行任务5
ThreadPoolExecutor-0_2在执行任务7
ThreadPoolExecutor-0_3在执行任务8
'''
.......

3.2 进程池

from concurrent.futures import ProcessPoolExecutor
from multiprocessing import current_process
import time

def task(i):
    time.sleep(1)
    print(f"{current_process().name}在执行任务{i+1}")
    time.sleep(1)
    return i**2

if __name__ == '__main__':
    fu_list = []
    pool = ProcessPoolExecutor(4)  #规定进程池有是个线程
    for i in range(20):  #模拟20个进程,task要做20次,4个进程负责做这个事情
        future = pool.submit(task,i)   #for循环一次,提交一次
        fu_list.append(future)   #先把提交的数据意义放到这个列表里面
    pool.shutdown()   # 关闭池的入口,不让你往里面再放东西
    for fu in fu_list:
        print(fu.result())
        
'''
SpawnProcess-1在执行任务1
SpawnProcess-2在执行任务2
SpawnProcess-3在执行任务3
SpawnProcess-4在执行任务4

SpawnProcess-1在执行任务5
SpawnProcess-2在执行任务6
SpawnProcess-3在执行任务7
SpawnProcess-4在执行任务8
.......
'''

四、提交任务的两种方式

4.1 同步

提交了一个任务,必须等任务执行完 (拿到返回值)才能执行下一行代码

import os
import time
import random
from multiprocessing import Process

def work(n):
    print(f'{n}: {os.getpid()} is running' )
    time.sleep(random.randint(1,3))
    print('%s:%s is done' %(n,os.getpid()))

if __name__ == '__main__':
    for i in range(3):  #这种就是同步了
        p=Process(target=work,args=(i,))
        p.start()

4.2 异步

提交了一个任务,不需要等任务执行完 (拿到返回值)才能执行下一行代码,就可以直接执行下一行

from concurrent.futures import ProcessPoolExecutor
from multiprocessing import current_process
import time

def task(i):
    time.sleep(1)
    print(f"{current_process().name}在执行任务{i+1}")
    time.sleep(1)
    return i**2

def parse(future):
    print(future.result())

if __name__ == '__main__':
    fu_list = []
    pool = ProcessPoolExecutor(4)  #规定进程池有是个线程
    for i in range(20):  #模拟20个进程,task要做20次,4个进程负责做这个事情
        future = pool.submit(task,i)   #for循环一次,提交一次
        future.add_done_callback(parse)
        # 为当前任务绑定了一个函数,在当前任务执行结束的时候会触发这个函数,
        # 会把future对象作为参数传给函数
        # 这个称之为回调函数,处理完了回来就调用这个函数.

转载于:https://www.cnblogs.com/yanjiayi098-001/p/11551068.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在多线程下注入 Spring Bean,我们需要注意一些问题。首先,Spring Bean 的依赖注入是线程安全的,因为 Spring 容器会保证 Bean 的实例唯一,并且在多线程环境中不会出现竞态条件。然而,如果我们在多线程环境下手动创建 Bean 实例并注入,就需要注意线程安全性。 为了在多线程下注入 Spring Bean,我们需要确保 Bean 的作用域是线程安全的。通常情况下,我们可以将 Bean 的作用域设置为 prototype,使得每个线程都拥有自己的 Bean 实例,避免线程间的竞态条件。 另外,我们需要注意在多线程环境下对 Bean 的操作是否会造成线程安全问题。比如在单例 Bean 中使用了非线程安全的对象或方法,就可能会导致线程安全问题。在这种情况下,我们需要使用同步机制来保证线程安全,或者考虑将 Bean 的作用域设置为 prototype。 在注入 Bean 的时候,我们还需要考虑是否需要进行依赖注入或者手动创建 Bean 实例。如果需要在多线程下注入 Bean,最好使用 Spring 容器进行依赖注入,这样可以保证线程安全性并且简化代码逻辑。 总的来说,在多线程下注入 Spring Bean,我们需要确保 Bean 的作用域是线程安全的,并且在操作 Bean 的过程中注意线程安全性,避免出现竞态条件。同时尽量使用 Spring 容器进行依赖注入,避免手动创建 Bean 实例造成线程安全问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值