线程状态切换

Java线程控制方法的作用及其区别:

  1. start:
    • 作用:启动线程,由虚拟机自动调度执行run()方法。
    • 区别:线程处于就绪状态。
  1. run:
    • 作用:线程逻辑代码块处理,JVM调度执行。
    • 区别:线程处于运行状态。
  1. sleep:
    • 作用:让当前正在执行的线程休眠(暂停执行)。
    • 区别:不释放锁。
  1. wait:
    • 作用:使得当前线程等待。
    • 区别:释放同步锁。
  1. notify:
    • 作用:唤醒在此对象监视器上等待的单个线程。
    • 区别:唤醒单个线程。
  1. notifyAll:
    • 作用:唤醒在此对象监视器上等待的所有线程。
    • 区别:唤醒多个线程。
  1. yield:
    • 作用:停止当前线程,让同等优先权的线程运行。
    • 区别:用Thread类调用。
  1. join:
    • 作用:使当前线程停下来等待,直至另一个调用join方法的线程终止。
    • 区别:用线程对象调用。

总结:

  • startrun 方法用于启动和执行线程,但它们的区别在于线程的状态不同。
  • sleep, wait, notify, notifyAll, yield, 和 join 等方法则用于控制线程的执行顺序和状态,包括暂停、等待、唤醒和其他线程交互操作。

 

  1. 从创建到就绪状态
public class ThreadExample {
    public static void main(String[] args) {
        Thread myThread = new MyThread();
        myThread.start();// 调用start方法,线程从创建变为就绪
    }
}
class MyThread extends Thread {
    public void run() {
        System.out.println("线程正在运行");
    }
}
    • 当调用线程对象的start()方法时,线程就从创建状态转换为就绪状态。这是线程生命周期中的第一次状态转换。例如,在Java中:
    • 这里myThreadnew之后处于创建状态,当执行start()方法后就进入就绪状态,等待CPU分配时间片来执行run()方法中的内容。
  1. 从就绪到运行状态
    • 当CPU的调度器决定将CPU时间片分配给某个就绪状态的线程时,该线程就从就绪状态转换为运行状态。这个过程是由操作系统的线程调度算法控制的。
    • 例如,在一个多线程环境中,假设有线程A、B、C都处于就绪状态。操作系统的调度算法(如时间片轮转、优先级调度等)会根据一定的规则选择一个线程,比如选择了线程A,那么线程A就从就绪状态转换为运行状态,开始执行它的run()方法中的代码。
  1. 从运行到就绪状态
    • 当正在运行的线程的时间片用完,或者有更高优先级的线程进入就绪状态并抢占CPU时,当前运行的线程就会从运行状态转换为就绪状态。
    • 例如,采用时间片轮转调度算法,假设一个线程的时间片是10ms,当这个线程运行了10ms后,CPU会暂停该线程的执行,将其放回就绪队列,等待下一次分配时间片。再比如,一个低优先级的线程正在运行,突然有一个高优先级的线程进入就绪状态,操作系统可能会暂停低优先级线程的运行,将其转换为就绪状态,而让高优先级线程开始运行。
  1. 从运行到阻塞状态
    • 当线程在运行过程中遇到某些阻塞事件时,会从运行状态转换为阻塞状态。如前所述,常见的阻塞事件包括等待I/O操作完成和等待获取锁。
    • 例如,一个线程在运行时需要从文件中读取数据,当它调用文件读取操作(如BufferedReader.readLine()方法)后,由于文件读取操作可能需要一些时间(取决于文件系统、网络等因素),线程就会进入阻塞状态,等待数据读取完成。或者当多个线程竞争一个对象锁时,一个线程在运行中尝试获取被其他线程占用的锁,就会进入阻塞状态,直到锁被释放。
  1. 从阻塞到就绪状态
    • 当导致线程阻塞的事件结束后,线程会从阻塞状态转换为就绪状态。例如,当线程等待的I/O操作完成后,或者线程成功获取到之前等待的锁时,它就会从阻塞状态转换为就绪状态。
    • 比如,前面提到的读取文件数据的线程,当文件数据读取完成后,线程就会从阻塞状态转换为就绪状态,等待CPU分配时间片再次运行。对于等待锁的线程,当占用锁的线程释放锁后,等待的线程就会从阻塞状态转换为就绪状态。
  1. 从运行到死亡状态
    • 当线程正常执行完run()方法中的所有代码或者因为未捕获的异常而退出run()方法时,线程就从运行状态转换为死亡状态。
    • 例如,一个线程的任务是计算1到10的和,在run()方法中通过循环完成计算后,run()方法执行完毕,线程就进入死亡状态。如果线程在运行过程中抛出一个未捕获的异常,如NullPointerException,并且没有在run()方法中进行处理,那么线程也会进入死亡状态。
posted @ 2024-11-15 13:55  CodeWhisperer001  阅读(2)  评论(0编辑  收藏  举报