zoukankan      html  css  js  c++  java
  • 线程的生命周期?什么时候会出现僵死进程?

    线程的生命周期及五种基本状态

    关于Java中线程的生命周期,首先看一下下面这张较为经典的图:
    

    线程生命周期

    • 新建(new Thread)

    当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。例如:Thread t1=new Thread();

    • 就绪(runnable)

    调用Thread类的start方法,线程已经被启动,进入就绪状态,正在等待被分配给CPU时间片,也就是说此时线程正在就绪队列中排队等候得到CPU资源。

    • 运行(running)

    线程获得CPU资源正在执行任务(执行run()方法),此时除非此线程自动放弃CPU资源或者有优先级更高的线程进入,线程将一直运行到结束或者时间片结束。

    • 堵塞(blocked)

    由于某种原因导致正在运行的线程让出CPU并暂停自己的执行,即进入堵塞状态。阻塞结束后线程进入就绪状态。
    堵塞的情况分三种:

    (一)等待堵塞:执行的线程执行wait()方法,JVM会把该线程放入等待池中。

    (二)同步堵塞:执行的线程在获取对象的同步锁时,若该同步锁被别的线程占用。则JVM会把该线程放入锁池中。

    (三)其它堵塞:执行的线程执行sleep()或join()方法,或者发出了I/O请求时。JVM会把该线程置为堵塞状态。
    当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完成时。线程又一次转入就绪状态。

    • 死亡(dead)

      当线程执行完毕(run方法运行结束)或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。

    线程间的状态转换

    链接url
    线程间的状态转换

    • 解释:

      1、线程的实现有两种方式,一是继承Thread类,二是实现Runnable接口,但无论如何,当我们new了这个对象后。线程就进入了初始状态;
      2、当该对象调用了start()方法,就进入可执行状态; 3、进入可执行状态后,当该对象被操作系统选中。获得CPU时间片就会进入执行状态;
      4、进入执行状态后情况就比較复杂了
      4.1、run()方法或main()方法结束后,线程就进入终止状态;
      4.2、当线程调用了自身的sleep()方法或其它线程的join()方法,就会进入堵塞状态(该状态既停止当前线程,但并不释放所占有的资源)。当sleep()结束或join()结束后。该线程进入可执行状态,继续等待OS分配时间片;
      4.3、线程调用了yield()方法,意思是放弃当前获得的CPU时间片,回到可执行状态,这时与其它进程处于同等竞争状态,OS有可能会接着又让这个进程进入执行状态。

      4.4、当线程刚进入可执行状态(注意,还没执行),发现将要调用的资源被synchroniza(同步),获取不到锁标记。将会马上进入锁池状态,等待获取锁标记(这时的锁池里或许已经有了其它线程在等待获取锁标记,这时它们处于队列状态,既先到先得),一旦线程获得锁标记后,就转入可执行状态。等待OS分配CPU时间片。

      4.5、当线程调用wait()方法后会进入等待队列(进入这个状态会释放所占有的全部资源,与堵塞状态不同)。进入这个状态后。是不能自己主动唤醒的,必须依靠其它线程调用notify()或notifyAll()方法才干被唤醒(因为notify()仅仅是唤醒一个线程,但我们由不能确定详细唤醒的是哪一个线程。或许我们须要唤醒的线程不可以被唤醒,因此在实际使用时,一般都用notifyAll()方法,唤醒有所线程),线程被唤醒后会进入锁池。等待获取锁标记。

    一个线程会因为以下原因而放弃CPU:

    1. 时间片用完了,java虚拟机让当前线程暂时放弃CPU,转到就绪状态,使其它线程获得运行机会。

    2. 当前线程因为某些原因而进入阻塞状态

    3. 线程结束运行

    线程在以下情况会停止:

    1. run方法正常执行完毕

    2. run方法执行过程中抛出一个未捕获的异常

    3. 调用stop方法(不推荐使用)

    进程的停止,当一个进程中所有的前台线程停止后,该进程结束。

    如果希望明确地让一个线程给另外一个线程运行的机会,可以采取以下办法。
    1. 调整各个线程的优先级
    2. 让处于运行状态的线程调用Thread.sleep()方法
    3. 让处于运行状态的线程调用Thread.yield()方法
    4. 让处于运行状态的线程调用另一个线程的join()方法

  • 相关阅读:
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    449. Serialize and Deserialize BST
    114. Flatten Binary Tree to Linked List
    199. Binary Tree Right Side View
    173. Binary Search Tree Iterator
    98. Validate Binary Search Tree
    965. Univalued Binary Tree
    589. N-ary Tree Preorder Traversal
    eclipse设置总结
  • 原文地址:https://www.cnblogs.com/inyu/p/13659069.html
Copyright © 2011-2022 走看看