基础 | 并发编程 - [线程状态 & 中断]

@

§1 线程状态

含义 是否存活 是否可以占有 CPU
是否可以自动解除阻塞
已占有CPU 涉及到的池 说明
New 新建 × × - 刚刚创建,尚未 start()
Runnable 就绪 × 可运行线程池 start(),等待获取 CPU 使用权
Running 运行 -
Blocked 阻塞 × × - 放弃 CPU 使用权
等待阻塞 × × 等待池 wait()
同步阻塞 × 锁池 抢锁没抢到,等待锁释放
其他阻塞 × - sleep()join()、IO 等
Dead 死亡 × × × - 完成或异常

图片

§2 用户态、内核态

区别
CPU 处于的状态不同
CPU 状态的不同,影响 CPU 执行指令的权限

为什么会划分用户态、内核态

  • 程序最终是由 CPU 指令执行的
  • CPU 指令中,有些比较上层、比较安全,有些比较底层、比较危险
    因此,不可能对应用程序直接开放所有 CPU 指令
  • 于是,CPU 指令被划分为不同的级别
    • intel 体系中,划分了 4 个级别,从高到低依次
      • Ring0,内核指令
      • Ring1,底层硬件驱动指令
      • Ring2,上层硬件驱动指令
      • Ring3,用户应用指令
    • Linux 中只划分 2 层 Ring0、Ring3
  • 线程处于用户态还是内核态,取决于线程 CPU 是在执行哪个级别的指令
    - Ring0,对应内核态,处理
    - Ring3,对应用户态

什么时候发生用户态、内核态的切换
下面场景线程会切换至内核态,但本质上将下列情况都是 中断

  • 用户应用通过 系统调用 使用内核态指令时
    • 内核态的指令不能直接由用户应用调用,因为危险
    • 但不能完全禁止用户应用调用内核态指令,因为确实会用到,比如磁盘读写
    • 只能折中的通过 系统调用 的方式迂回
    • 系统调用本质上属于中断,只不过是软件中断
  • 用户应用发生异常时
  • 用户应用涉及到的外设中断时

§2 线程停止 & 中断

推荐的停止线程的方式
示例代码(通过中断:先中断,处理中断时停止)

public void run(){
	while(true){
		if(Thread.currentThread().isInterrupted()){
			//结束线程
			return;
		}
		try{
			//do sth
			Thread.sleep(2000);
		}catch(InterruptedException e){
			//结束线程
			return;
		}
	}
}
  • 线程只应该由自己停止或中断自己
    因此 Thread.stopThread.suspendThread.resume 都过期了
  • java 中无法立即停止一个线程
  • 中断是用于停止线程的 协商机制
  • 中断的具体过程没有 java 原生语法支持
    即需要自己实现
  • Thread.interrupt 仅将线程的中断标志位置为 true,推荐的停止线程的方式
    所以对可能中断的线程,需要监听此标志位,发现它为 true 时,需要在业务中编码实现对应逻辑

中断方法

  • Thread.interrupt) 中断方法,但作用仅限于设置标志位
  • Thread.interrupted() 静态方法,判断当前线程是否被中断,然后将中断标志位清除
    这意味着,此方法认为,当调用此方法后,就会对当前线程的中断状态进行处理
  • Thread.isInterrupted(),实例方法,判断当前线程是否被中断

子线程的停止

  • 子线程是业务线程:线程停止不影响子线程
  • 子线程是守护线程:线程停止子线程也停止

§3 线程通信

synchronized 锁:

  • wait
  • notigy
  • notifyAll

线程:

  • join

Lock(Condition):

  • lock
  • unlock
  • await
  • signal
  • signalAll

BlockingQueue:

  • 队列为空时,读阻塞
  • 队列满载时,写阻塞
posted @ 2025-05-20 14:55  问仙长何方蓬莱  阅读(8)  评论(0)    收藏  举报