线程

概述

多线程,英文multithreading

进程可进一步细化为 线程,是一个程序内部的一条执行路径。每个进程都有一个线程,称之为 主线程

线程也是实现多任务的方式

操作系统要实现多任务,通过多进程实现
一个进程要实现多任务,通过多线程实现

类比

  • 操作系统
    相当于学校
  • 多进程
    相当于多个老师,每个老师独立做一件事,有时也会和其他老师协作,共同做一件事
  • 多线程
    相当于老师在做多件事,一天中要上课、备课、批作业、刷抖音、打游戏、评职称

线程和进程的关系

  1. 一个线程只能属于一个进程,但是一个进程可以拥有多个线程。多线程处理就是允许一个进程中在同一时刻执行多个任务。

  2. 线程是一种轻量级的进程,与进程相比,线程给操作系统带来侧创建、维护、和管理的负担要轻,意味着线程的代价或开销比较小。

例子

  • TIM、QQ等,只有一个进程,但是可以跟多个好友聊天,收发消息,就是通过多线程实现的
  • 迅雷等下载软件快,就是因为可以多个线程同时下载,如下图:

应用场景

IO密集型程序,IO操作大部分时间都在等待IO操作完成(因为IO的速度远远低于CPU和内存的速度),不占用CPU,一般使用多线程

如:网络编程、磁盘IO、内存读写数据等

优点

  • 更好的利用CPU
  • 使用线程可以把占据时间长的程序中的任务放到后台去处理
  • 在GUI界面编程中大量使用,比如用户点击按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度
  • 在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用。在这种情况下可以释放一些珍贵的资源如内存占用等等。

缺点

  • 如果有大量的线程,会影响性能,因为操作系统需要在它们之间切换。
  • 更多的线程需要更多的内存空间。
  • 线程没有自己的独立空间,一旦崩溃导致进程崩溃。
  • 线程的中止需要考虑其对程序运行的影响。
  • 内存在多个线程间共享
  • 防止线程死锁

在windows系统中查看线程

调度策略

抢占式
与操作系统有关,有的操作系统可以设置线程优先级,优先级高的线程优先抢占CPU
有的操作系统不支持优先级

线程的分类

  1. 主线程:当一个程序启动时,就有一个进程被操作系统(OS)创建,与此同时一个线程也立刻运行,该线程通常叫做程序的主线程(Main Thread)。每个进程至少都有一个主线程,主线程通常最后关闭。

  2. 子线程:在程序中创建的其他线程,相对于主线程来说就是这个主线程的子线程

  3. 守护线程(daemon thread):也称后台线程,对线程的一种标识。守护线程为其他线程提供服务,如果剩下的全是守护线程时,进程退出。

  4. 前台线程:也称用户线程,相对于守护线程的其他线程称为前台线程

线程的生命周期

五种状态:

  • 新建(new): 新创建的线程经过初始化后,进入就绪(Runnable)状态
  • 就绪(Runnable):等待线程调度。调度后进入运行状态
  • 运行(Running):当就绪的线程被调度并获得CPU时,便进入运行状态
  • 阻塞(Blocked):暂停运行,解除阻塞后进入Runnable状态重新等待调度
  • 死亡(Dead):线程方法执行完毕返回或者异常终止

从“运行”进入“阻塞”(Blocked):

  • 同步:线程中获取同步锁,但是资源已经被其他线程锁定时,进入Locked状态,直到该资源可获取(获取的顺序由Lock队列控制)
  • 睡眠:线程运行sleep()或join()方法后,线程进入Sleeping状态。区别在于sleep等待固定的时间,而join是等待子线程执行完。当然join也可以指定一个“超时时间”。从语义上来说,如果两个线程a,b, 在a中调用b.join(),相当于合并(join)成一个线程。最常见的情况是在主线程中join所有的子线程。
  • 等待:线程中执行wait()方法后,线程进入Waiting状态,等待其他线程的通知(notify)。

原文出处:/show_1EF2miur3rg0.html