浅谈线程的6种状态 - 极悦
首页 课程 师资 教程 报名

浅谈线程的6种状态

  • 2020-11-06 17:48:38
  • 1478次 极悦

在正式学习Java多线程这一重点内容之前,我们先来了解一下线程有哪些状态,深入理解线程的6种状态将会有助于后面对Thread类中的方法的理解。


一般情况下,线程分为以下6个状态:

1.创建(new)状态: 准备好了一个多线程的对象

2.就绪(runnable)状态: 调用了start()方法, 等待CPU进行调度

3.运行(running)状态: 执行run()方法

4.阻塞(blocked)状态: 线程为等待某个对象的“锁”而暂时放弃cpu的使用权,且不再参与CPU使用权竞争。直到条件满足时,重新回到就绪状态,重新参与竞争CPU。

5.等待(waiting):线程无限等待某个对象的“锁”,或等待另一个线程结束的状态到来。

6.终止(dead)状态: 线程销毁


当需要新起一个线程来执行某个子任务时,就创建了一个线程。但是线程创建之后,不会立即进入就绪状态,因为线程的运行需要一些条件(比如内存资源,程序计数器、Java栈、本地方法栈都是线程私有的,所以需要为线程分配一定的内存空间),只有线程运行需要的所有条件满足了,才进入就绪状态。

当线程进入就绪状态后,不代表立刻就能获取CPU执行时间,也许此时CPU正在执行其他的事情,因此它要等待。当得到CPU执行时间之后,线程便真正进入运行状态。


线程在运行状态过程中,可能有多个原因导致当前线程不继续运行下去,比如用户主动让线程睡眠(睡眠一定的时间之后再重新执行)、用户主动让线程等待,或者被同步块给阻塞,此时就对应着多个状态:time waiting(睡眠或等待一定的事件)、waiting(等待被唤醒)、blocked(阻塞)。

当由于突然中断或者子任务执行完毕,线程就会被消亡。

下面这副图描述了线程从创建到消亡之间的状态:

image.png


在有些教程上将blocked、waiting、time waiting统称为阻塞状态,这个也是可以的,只不过这里我们需要将线程的状态和Java中的方法调用联系起来,所以将waiting和time waiting两个状态分离出来。

注:sleep和wait的区别:

sleep是Thread类的方法,wait是Object类中定义的方法.

Thread.sleep不会导致锁行为的改变, 如果当前线程是拥有锁的, 那么Thread.sleep不会让线程释放锁.

Thread.sleep和Object.wait都会暂停当前的线程. OS会将执行时间分配给其它线程. 区别是, 调用wait后, 需要别的线程执行notify/notifyAll才能够重新获得CPU执行时间。


下面通过示例演示sleep()是不会释放锁的。

SleepLockTest.java的源码

public class SleepLockTest{

private static Object obj = new Object();

public static void main(String[] args){

ThreadA t1 = new ThreadA("t1");

ThreadA t2 = new ThreadA("t2");

t1.start();

t2.start();

}

static class ThreadA extends Thread{

public ThreadA(String name){

super(name);

}

public void run(){

// 获取obj对象的同步锁

synchronized (obj) {

try {

for(int i=0; i <10; i++){

System.out.printf("%s: %d\n", this.getName(), i);

// i能被4整除时,休眠100毫秒

if (i%4 == 0)

Thread.sleep(100);

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

}


主线程main中启动了两个线程t1和t2。t1和t2在run()会引用同一个对象的同步锁,即synchronized(obj)。在t1运行过程中,虽然它会调用Thread.sleep(100);但是,t2是不会获取cpu执行权的。因为,t1并没有释放“obj所持有的同步锁”!若我们注释掉synchronized (obj)后再次执行该程序,t1和t2是可以相互切换的。


以上就是关于线程状态的内容讲解,也是本站的多线程教程中的开篇内容,想要系统地学习多线程,弄懂线程之间的状态转换是必不可少的学习内容,有利于我们理解多线程中的各种Thread类的方法和多线程编程。


选你想看

你适合学Java吗?4大专业测评方法

代码逻辑 吸收能力 技术学习能力 综合素质

先测评确定适合在学习

在线申请免费测试名额
价值1998元实验班免费学
姓名
手机
提交