Java多线程之线程的状态以及线程间协作通信导致的线程状态转换

时间:2021-07-21 18:14:51

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6561589.html 

    一:线程的状态以及变化图

     Java中线程中状态可分为五种:New(新建状态),Runnable(就绪状态),Running(运行状态),Blocked(阻塞状态),Dead(死亡状态)。

  New:新建状态,当线程创建完成时为新建状态,即new Thread(...),还没有调用start方法时,线程处于新建状态。

  Runnable:就绪状态,当调用线程的的start方法后,线程进入就绪状态,等待CPU资源。处于就绪状态的线程由Java运行时系统的线程调度程序(thread scheduler)来调度。

  Running:运行状态,就绪状态的线程获取到CPU执行权以后进入运行状态,开始执行run方法。

  Blocked:阻塞状态,线程没有执行完,由于某种原因(如,I/O操作等)让出CPU执行权,自身进入阻塞状态。

  Dead:死亡状态,线程执行完成或者执行过程中出现异常,线程就会进入死亡状态。

      Java多线程之线程的状态以及线程间协作通信导致的线程状态转换

    (图来自牛客网,如有冒犯,请告知删除。)

 

    二:线程间协作通信以及其导致的状态变化

      1:线程间的同步协作

         由syncrhoized同步锁、ReentrantLock、ReadWriteLock等待同步机制,实现线程之间的同步。

         线程获得锁则进入就绪态,等待CPU调度进入运行态;

         线程申请被占用的锁,则进入阻塞态,让出CPU使用权。直到获得该锁后,重新进入就绪态,等待CPU调度进入运行态。

 

      2:线程间的通信协作

         在获得锁而执行的线程执行时,执行到某处时需要申请同一把锁的其他线程先执行,此时就需要让出同步锁以及CPU(进入阻塞态),让其他线程先获取同步锁以及CPU而执行。直到其他线程执行完并释放同步锁后通知它唤醒(就绪态),才接着申请同步锁以及CPU而继续执行下去(运行态)。

         这个线程之间 让出资源、挂起、唤醒 就是通过线程的通信来实现的。

         syncrhoized加锁的线程的wait()/notify()/notifyAll()以及ReentrantLock加锁的线程的Condition调用await()/signal()/signalAll()就是具体的线程通信。  

 

      3:线程自身的动作

          线程自身可以通过调用 sleep() 方法进入阻塞态,暂时让出CPU资源(但是不释放锁),休眠时间过后自动恢复就绪态等待CPU调度执行;

          线程自身可以通过调用 yield() 方法由运行态变为就绪态;这个过程称为“让步”,即正在运行的线程让出CPU给就绪态中的线程先执行一下,自己则回到就绪态中等待CPU再次调度自己执行;

          线程可以在自身执行过程中,通过 其他线程对象.join() 方法把已经启动的其他线程先执行完 ,再继续执行自身的余下操作。可以通过这个方法来实现线程之间顺序执行。