多线程总结二:线程的状态转换

转自:http://zy19982004.iteye.com/blog/1626916

一.线程的状态图

二.初始状态

  1. 实现Runnable接口和继承Thread可以得到一个线程类,new一个实例出来,线程就进入了初始状态

三.可运行状态

  1. 可运行状态只是说你资格运行,调度程序没有挑选到你,你就永远是可运行状态。
  2. 调用线程的start()方法,此线程进入可运行状态。
  3. 当前线程sleep()方法结束,其他线程join()结束,等待用户输入完毕,某个线程拿到对象锁,这些线程也将进入可运行状态。
  4. 当前线程时间片用完了,调用当前线程的yield()方法,当前线程进入可运行状态。
  5. 锁池里的线程拿到对象锁后,进入可运行状态。

四.运行状态

  1. 线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态。这也是线程进入运行状态的唯一一种方式。

五.死亡状态

  1. 当线程的run()方法完成时,或者主线程的main()方法完成时,我们就认为它死去。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦死亡,就不能复生。
  2. 在一个死去的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。

六.阻塞状态

  1. 当前线程T调用Thread.sleep()方法,当前线程进入阻塞状态。
  2. 运行在当前线程里的其它线程t2调用join()方法,当前线程进入阻塞状态。
  3. 等待用户输入的时候,当前线程进入阻塞状态。

七.等待队列(本是Object里的方法,但影响了线程)

  1. 调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj) 代码段内。
  2. 与等待队列相关的步骤和图
  • 线程1获取对象A的锁,正在使用对象A。
  • 线程1调用对象A的wait()方法。
  • 线程1释放对象A的锁,并马上进入等待队列。
  • 锁池里面的对象争抢对象A的锁。
  • 线程5获得对象A的锁,进入synchronized块,使用对象A。
  • 线程5调用对象A的notifyAll()方法,唤醒所有线程,所有线程进入锁池。||||| 线程5调用对象A的notify()方法,唤醒一个线程,不知道会唤醒谁,被唤醒的那个线程进入锁池。
  • notifyAll()方法所在synchronized结束,线程5释放对象A的锁。
  • 锁池里面的线程争抢对象锁,但线程1什么时候能抢到就不知道了。||||| 原本锁池+第6步被唤醒的线程一起争抢对象锁。

八.锁池状态

  1. 当前线程想调用对象A的同步方法时,发现对象A的锁被别的线程占有,此时当前线程进入锁池状态。简言之,锁池里面放的都是想争夺对象锁的线程。
  2. 当一个线程1被另外一个线程2唤醒时,1线程进入锁池状态,去争夺对象锁。
  3. 锁池是在同步的环境下才有的概念,一个对象对应一个锁池。

九.几个方法的比较

  1. Thread.sleep(long millis),一定是当前线程调用此方法,当前线程进入阻塞,但不释放对象锁,millis后线程自动苏醒进入可运行状态。作用:给其它线程执行机会的最佳方式。
  2. Thread.yield(),一定是当前线程调用此方法,当前线程放弃获取的cpu时间片,由运行状态变会可运行状态,让OS再次选择线程。作用:让相同优先级的线程轮流执行,但并不保证一定会轮流执行。实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。Thread.yield()不会导致阻塞。
  3. t.join()/t.join(long millis),当前线程里调用其它线程1的join方法,当前线程阻塞,但不释放对象锁,直到线程1执行完毕或者millis时间到,当前线程进入可运行状态。
  4. obj.wait(),当前线程调用对象的wait()方法,当前线程释放对象锁,进入等待队列。依靠notify()/notifyAll()唤醒或者wait(long timeout)timeout时间到自动唤醒。
  5. obj.notify()唤醒在此对象监视器上等待的单个线程,选择是任意性的。notifyAll()唤醒在此对象监视器上等待的所有线程。

十.两个疑问

  1. 当对象锁被某一线程释放的一瞬间,锁池里面的哪个线程能获得这个锁?随机?队列FIFO?or sth else?
  2. 等待队列里许许多多的线程都wait()在一个对象上,此时某一线程调用了对象的notify()方法,那唤醒的到底是哪个线程?随机?队列FIFO?or sth else?java文档就简单的写了句:选择是任意性的。
时间: 2024-10-13 07:50:39

多线程总结二:线程的状态转换的相关文章

java 22 - 18 多线程之 线程的状态转换、线程组

线程的状态转换图解:..博客暂时不能上传图片 线程的线程组: 线程组: 把多个线程组合到一起.    它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制. 首先创建一个Runnable的实现类 public class MyRunnable implements Runnable { public void run() { for(int x = 0; x < 10 ; x++){ System.out.println(x); } } } 先看看默认状态下,线程都会保存在哪个线程

2.线程的状态转换以及基本操作

在上一篇文章中并发编程的优缺点谈到了为什么花功夫去学习并发编程的技术,也就是说我们必须了解到并发编程的优缺点,我们在什么情况下可以去考虑开启多个线程去实现我们的业务,当然使用多线程我们应该着重注意一些什么,在上一篇文章中会有一些讨论.那么,说了这么多,无论是针对面试还是实际工作中作为一名软件开发人员都应该具备这样的技能.万事开头难,接下来就应该了解如何新建一个线程?线程状态是怎样转换的?关于线程状态的操作是怎样的?这篇文章就主要围绕这三个方面来聊一聊. 1. 新建线程 一个java程序从main

Java多线程学习之线程的状态及中断线程

线程的状态 新建(new):当线程被创建时,它只会短时间处于这种状态.它已经分配了必要的系统资源,完成了初始化.之后线程调度器将把这个线程转变为可运行或者阻塞状态: 就绪(Runnable):在这种状态下,只要调度器分配时间片给线程,线程就可以运行了: 阻塞(Blocked):有某个条件阻止线程运行,调度器将忽略阻塞状态的线程,不会分配时间片给它,直到线程进入就绪状态,它才有可能执行: 死亡(Dead):处于死亡或者终结状态的线程将不再是可调度的,并且也不会被分配到时间片.任务死亡的方式通常是从

线程的状态转换

新建状态:新创建了一个线程对象. 就绪状态:线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权. 运行状态:就绪状态的线程获取了CPU,执行程序代码. 阻塞状态:阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行.直到线程进入就绪状态,才有机会转到运行状态.阻塞的情况分三种: (1)等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中. (2)同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别

Java多线程及线程状态转换

Java实现多线程的方法有两种,一是继承Thread类.二是实现Runnable接口. 一.继承Thread类 public class ThreadTest extends Thread { @Override public void run() { System.out.println("this thread name is:"+Thread.currentThread().getName()); } /** * @param args */ public static void

线程的状态和生命周期

http://blog.csdn.net/lonelyroamer/article/details/7949969 线程的状态转换: 1.新建状态用new Thread()建立一个线程对象后,该线程对象就处于新生状态. 2.就绪状态通过调用线程的start方法进入就绪状态(runnable).注意:不能对已经启动的线程再次调用start()方法,否则会出现Java.lang.IllegalThreadStateException异常.处于就绪状态的线程已经具备了运行条件,但还没有分配到CPU,处

001 线程的状态

一 . 概述 线程的整个生命周期是在不断切换其状态的. 在jdk中的Thread类之中有一个枚举类,在这个枚举类之中定义了线程的所有状态. 二 .线程的状态 public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED; } 上面的所有状态里面在加上一running状态总共有7个状态. [1]new状态: 当一个线程创建之后就处于new状态. [2]runnable状态: 就绪状态,该线程是可以在抢占

线程生命状态

线程的状态转换: 1.新建状态用new Thread()建立一个线程对象后,该线程对象就处于新生状态. 2.就绪状态通过调用线程的start方法进入就绪状态(runnable).注意:不能对已经启动的线程再次调用start()方法,否则会出现Java.lang.IllegalThreadStateException异常.处于就绪状态的线程已经具备了运行条件,但还没有分配到CPU,处于线程就绪队列(就绪池),等待系统为其分配CPU.Note:如果希望子线程调用start()方法后立即执行,可以使用

Java基础系列之(二) - 线程

一.线程的实现方式 1.继承Thread 2.实现Runnable接口 二.线程的状态 1.New(新生线程) 当你new一个Thread,newThread(r),这时处于线程的新生状态,此时程序还没有真正的运行. 2.Runnable(可运行的) 当启动start()方法时,此时线程处于可运行状态,不一定运行之中,这取决与线程是否得到CPU的运行时间片.事实上,一个线程并不是一直处于运行状态,偶尔需要被中断,让其他线程有运行的机会. 3.Blocked(被阻塞) 当发生以下情况被阻塞 -线程