前言
上篇文章讲解了多线程的停止方法。我们本篇文章来讲讲多线程的运行状态。
一、多线程的运行状态。
我们都知道,线程分为新建、就绪、运行、阻塞、死亡这几种状态,这些状态分别是什么意思呢,来看一下。
新建:指的是线程新创建出来,并没有运行start方法,这时候就是新建状态,没有运行代码。
就绪:就绪状态指的是线程调用了start方法,线程准备就绪,争抢cpu,当抢到cpu的时候,才可以进行执行代码。因为在单CPU的计算机系统中,不可能同时运行多个线程,一个时刻仅有一个线程处于运行状态。因此此时可能有多个线程处于就绪状态。
运行:运行值得是线程抢到了cpu的后,进入运行状态,执行run方法, 开始实际的代码运行。
等待:等待是join或者wait之后线程需要等待所依赖或被唤醒的等待状态。
阻塞:阻塞状态是线程运行中,由于某些原因进入阻塞状态。例如线程通过sleep方法进入睡眠状态,等待触发某个条件。阻塞状态就是正在运行的线程没有结束,暂时让出cpu,这时候其他处于运行状态的线程就可以获取cpu,进入运行状态。
死亡:死亡状态是指线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。
二、线程状态的变化
线程的状态变化如下:
image.gif
其中涉及到了yield方法和join方法,来讲解一下。
yield方法是:暂停当前执行的线程,放弃cpu资源,执行其他线程。是让线程从运行状态回到可运行状态,但是实际无法保证yield()可以达到让步的目的,因为当前线程可以能会再次抢占到CPU。在大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果
join方法是:Join把指定的线程加入到当前线程,可以把交替执行的两个线程合并为顺序执行,例如线程B调用线程A的join方法,那么将先执行完A线程,才会执行线程B,如下面代码所示
/**
* @version 1.0
* @Description joinDemo
* @Author wb.yang
*/
public class JoinDemo {
/**
* 女神
*/
static class Goddess implements Runnable {
private Thread thread;
public Goddess(Thread thread) {
this.thread = thread;
}
@Override
public void run() {
System.out.println("Goddess开始排队打饭.....");
try {
if (thread != null) {
thread.join();
}
} catch (InterruptedException e) {
}
//休眠2秒
SleepTools.second(2);
System.out.println(Thread.currentThread().getName()
+ " Goddess打饭完成.");
}
}
/**
* 女神的男朋友
*/
static class GoddessBoyfriend implements Runnable {
@Override
public void run() {
//休眠2秒
SleepTools.second(2);
System.out.println("GoddessBoyfriend开始排队打饭.....");
System.out.println(Thread.currentThread().getName()
+ " GoddessBoyfriend打饭完成.");
}
}
public static void main(String[] args) throws Exception {
// 女神的男朋友
GoddessBoyfriend goddessBoyfriend = new GoddessBoyfriend();
Thread gbf = new Thread(goddessBoyfriend);
// 女神,把女神的男朋友线程放入女神中
Goddess goddess = new Goddess(gbf);
// 汤姆
Thread tom = new Thread(goddess);
tom.start();
gbf.start();
System.out.println("汤姆开始排队打饭.....");
tom.join();
//让主线程休眠2秒
SleepTools.second(2);
System.out.println(Thread.currentThread().getName() + " 汤姆打饭完成.");
}
}
image.gif
从代码中可以看出总共有三个线程,汤姆,女神,女神男朋友三个线程,如果正常的线程的话,执行顺序是不一定的,就是说这个是那个线程都有可能先执行完,然后看看执行结果把。
image.gif
从结果中看出,线程是有执行顺序的,这就是因为我们用了join方法,在汤姆的线程中调用了女神线程的join方法,所以汤姆线程就要等待女神线程先执行完毕,而在女神线程中,有调用的女神男朋友的线程,所以又要等待女神男朋友线程的执行完毕,所以最终结果就是女神男朋友先打完饭,然后是女神,最后是汤姆。这就是join方法的作用。
总结
1.线程的五种状态,新建、就绪、运行、阻塞、死亡
2.线程的两个方法,yield和join方法







网友评论