Java教程

多线程

本文主要是介绍多线程,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

>多线程

>>多任务

简单来说就是操作系统可以同时运行多个任务

并发:任务数大于CPU核数,通过操作系统的各种任务调度算法,实现多个任务‘一起’执行,比如在单核CPU下需要同时处理3个任务,这就是并发,单核CPU在开启任务一会立马开启任务二,任务三也同理,这段时间内交替执行任务的方式就是并发。此外单核CPU只会存在并发的情况,不存在并行的情况。

并行:就是在同一时刻一起执行多个任务,比如你有8核的CPU,每个CPU执行一个任务,其中任务数<=CPU核数,就可以进行并行的多任务执行

同步:同步是指完成事务的逻辑顺序执行的,即先执行第一个事务,如果阻塞了,会一直等待,直到这个事务完成以后在执行第二个事务。

异步:异步和同步是相对的,异步是指在调用这个事务以后,不会等待这个事务的处理结果,直接处理第二个事务去,通过状态,通知,回调来通知调用者处理结果

>>_thread模块

# _thread 实现多线程
'''
_thread 常用模块
def start_new_thread(function,args,kwargs=None) 启动一个新的线程  function 线程处理函数  args 传递给线程的参数 元组类型 kwargs 可选参数
def allocate_lock() 分配锁对象
def exit() 线程退出
def get_ident() 获取线程表示符
def interrupt_main() 终止主线程 会产生 KeyboardInterrupt异常
'''

# 利用_thread 模块创建多线程
import _thread
import time


def work(thread_name):
    print('哟西 这是第%s个线程' % thread_name)
    time.sleep(1)

def main():
    for i in range(1,5):
        _thread.start_new_thread(work,('--%s'% i,))
    time.sleep(30)  # 主进程添加延迟  保证子线程执行完成
if __name__ == '__main__':
    main()

>>Treading模块

# threading实现多线程
'''
常用方法
def init(self,group=None,target=None,name=None,args=(),kwargs=None,*,daemon=None)
def start(self) 线程启动
def run(self) 线程操作主体 若没设置target 处理函数 则执行方法
def join(self,timeout=None)
def name(self) 获取线程名称
def ident(self) 获取线程标识
def is_alive()  判断线程存活状态
'''

# threading 创建多线程
import threading
import time


def work(thread_name):
    print('哟西 这是第%s个线程' % thread_name)
    time.sleep(1)

def main():

        thraeds=[threading.Thread(target=work,args=('---%s'%i,))for i in range(1,5)]
        for thraed in thraeds:
            thraed.start()
        time.sleep(3)  # 主进程添加延迟  保证子线程执行完成
if __name__ == '__main__':
    main()
    
# 获取线程信息
import threading
import time


def work(thread_name):
    print('哟西 这是第%s个线程' % thread_name)
    print(threading.current_thread().ident, threading.current_thread().name)
    print('')
    time.sleep(1)

def main():

        thraeds=[threading.Thread(target=work,args=('---%s'%i,))for i in range(20)]
        for thraed in thraeds:
            thraed.start()

if __name__ == '__main__':
    main()
# 将线程设置成类  设置守护进程
import threading
import time
class myThread(threading.Thread):
    def __init__(self, threadname, delay, count):
        super().__init__(name=threadname)
        self._delay = delay
        self._count = count

    def run(self):
        for num in range(self._count):
            time.sleep(1)
            print('线程id:%s,线程名称:%s - %s'
                  % (threading.current_thread().ident, threading.current_thread().getName(), num))

def main():
    thr1=myThread('用户进程', 1, 10)
    thr1.start()
    thr2= myThread('守护进程', 1, 999)
    thr2.setDaemon(True)  # 将线程2 设置成守护进程
    thr2.start()

if __name__ == '__main__':
    main()

>>线程同步

# 线程同步&互斥锁
# Semaphore 实现资源并发控制
import threading
import time
def work_handle(sem):
    if sem.acquire():
        print('请%s前往窗口,办理个人业务 '% threading.current_thread().getName())
        time.sleep(3)  # 模拟银行办理业务时间
        sem.release()  # 释放资源
def main():
    sem = threading.Semaphore(2)
    threading_list=[threading.Thread(target=work_handle,args=(sem,),name='客户%s'% num) for num in range(10)]
    for thr in threading_list:
        thr.start()
if __name__ == '__main__':
    main()

>>多线程共享全局变量

# 共享全局变量
import threading
num =0
def thr1():
    global num
    for i in range(0,1000000):
        num = num+1

def thr2():
    global num
    for i in range(0,1000000):
        num = num+1

if __name__ == '__main__':
    for i in range(5):
        num = 0
        t1 = threading.Thread(target=thr1)
        t2 = threading.Thread(target=thr2)
        t1.start()
        t2.start()
        t1.join()
        t2.join()
        print('计算结果为%s' % num)
        
》》》计算结果为1647829
	计算结果为2000000
	计算结果为2000000
	计算结果为1000000
	计算结果为1645209
    # 创建两个线程 各自加了100000次 累计输出应该是200000 调用了5次应该每次的输出应该一样的 为什么不一样呢,应为像个线程同时运行,不知到谁先谁后,累加1时,线程1 刚累加等于1  想赋值给 num 结果 线程2 提前赋值给了num 结果就是1了  累计次数越多 误差越大 

&互斥锁解决资源问题(lock()和Rlock())

# 互斥锁

import threading
num =0

def thr1(lock):
    lock.acquire()
    global num
    for i in range(0,1000000):
        num = num+1
    lock.release()

def thr2(lock):
    lock.acquire()
    global num
    for i in range(0,1000000):
        num = num+1
    lock.release()
if __name__ == '__main__':
    lock = threading.Lock()
    for i in range(5):
        num = 0
        t1 = threading.Thread(target=thr1,args=(lock,))
        t2 = threading.Thread(target=thr2,args=(lock,))
        t1.start()
        t2.start()
        t1.join()
        t2.join()
        print('计算结果为%s' % num)
import threading
num =0

def thr1(lock):
    lock.acquire()
    global num
    for i in range(0,1000000):
        num = num+1
    lock.release()

def thr2(lock):
    lock.acquire()
    global num
    for i in range(0,1000000):
        num = num+1
    lock.release()
if __name__ == '__main__':
    lock = threading.RLock()
    for i in range(5):
        num = 0
        t1 = threading.Thread(target=thr1,args=(lock,))
        t2 = threading.Thread(target=thr2,args=(lock,))
        t1.start()
        t2.start()
        t1.join()
        t2.join()
        print('计算结果为%s' % num)

>>死锁

一直等待对方释放锁的情况就是死锁
# 死锁

import threading

def get_value(index,lock,list1):
    lock.acquire()

    if index >= len(list1):
        print('超出索引范围')

        return
    data = list1[index]
    print(data)
    lock.release()

def main():
    lock = threading.Lock()
    for i in range(10):
        t =threading.Thread(target=get_value,args=(3,lock,[1,2]))
        t.start()

if __name__ == '__main__':
    main()
# 解决死锁问题 可以在acquire()里面添加超时时间 超过时间自动解锁 

# 死锁

import threading

def get_value(index,lock,list1):
    lock.acquire(timeout=2)

    if index >= len(list1):
        print('超出索引范围')

        return
    data = list1[index]
    print(data)
    lock.release()

def main():
    lock = threading.Lock()
    for i in range(10):
        t =threading.Thread(target=get_value,args=(3,lock,[1,2]))
        t.start()

if __name__ == '__main__':
    main()

>>定时调度

# 定时调度是一种基于线程任务的操作管理 可以实现在末段时间的任务的重复执行

# 通过sched模块实现定时调度操作
'''
delay=0 调度任务启动的延迟时间 如果是0 表示立即启动
priority=0 多个调度任务的启动优先级 
action=func 设置任务的调度处理函数
argument = (参数,) 调度函数的参数 必须填可迭代对象  
'''
import sched


def work_1():
    print('我是第一个任务')

def work_2():
    print('我是第二个任务')

def work_3():
    print('我是第三个任务')

def main():
    sch =sched.scheduler()
    s1=sch.enter(delay=2,priority=1,action=work_1,)
    s2= sch.enter(delay=6, priority=3, action=work_2)
    s3 = sch.enter(delay=4, priority=2, action=work_3)
    sch.run()
if __name__ == '__main__':

    main()
这篇关于多线程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!