JAVA多线程展示线程状态1

1、线程状态

Java中的线程状态被定义在了java.lang.Thread.State中,State枚举类的源码如下:

public class Thread { 
	public enum State { 
		/* 新建 */ 
		NEW , 
		/* 可运行状态 */ 
		RUNNABLE , 
		/* 阻塞状态 */ 
		BLOCKED , 
		/* 无限等待状态 */ 
		WAITING , 
		/* 计时等待 */ 
		TIMED_WAITING , 
		/* 终止 */ 
		TERMINATED; 
		}
		// 获取当前线程的状态 
	public State getState() { 
		return jdk.internal.misc.VM.toThreadState(threadStatus); 
		} 
	}

通过源码我们可以看到Java中的线程存在6种状态,每种线程状态的含义如下

线程状态具体含义
NEW一个尚未启动的线程的状态。也称之为初始状态、开始状态。线程刚被创建,但是并未启动。还没调用start方法。MyThread t = new MyThread()只有线程象,没有线程特征。
RUNNABLE当我们调用线程对象的start方法,那么此时线程对象进入了RUNNABLE状态。那么此时才是真正的在JVM进程中创建了一个线程,线程一经启动并不是立即得到执行,线程的运行与否要听令与CPU的调度,那么我们把这个中间状态称之为可执行状态(RUNNABLE)也就是说它具备执行的资格,但是并没有真正的执行起来而是在等待CPU的度。
BLOCKED当一个线程试图获取一个对象锁,而该对象锁被其他的线程持有,则该线程进入Blocked状态;当该线程持有锁时,该线程将变成Runnable状态。
WAITING一个正在等待的线程的状态。也称之为等待状态。造成线程等待的原因有两种,分别是调用Object.wait()、join()方法。处于等待状态的线程,正在等待其他线程去执行一个特定的操作。例如:因为wait()而等待的线程正在等待另一个线程去调用notify()或notifyAll();一个因为join()而等待的线程正在等待另一个线程结束。
TIMED_WAITING一个在限定时间内等待的线程的状态。也称之为限时等待状态。造成线程限时等待状态的原因有三种,分别是:Thread.sleep(long),Object.wait(long)、join(long)。
TERMINATED一个完全运行完成的线程的状态。也称之为终止状态、结束状态

各个状态的转换,如下图所示:
线程状态

2、代码示例

需求:编写一段代码,演示TIME_WAITING的状态转换;

为了简化我们的开发,本次我们使用匿名内部类结合lambda表达式的方式使用多线程。
代码实现:

public class ThreadStateDemo01 {
    public static void main(String[] args) throws InterruptedException {
        //定义一个内部线程
        Thread thread = new Thread(() -> {
            System.out.println("次2.执行thread.start()之后,["+Thread.currentThread().getName()+"]线程的状态:" + Thread.currentThread().getState());
            try {
                //休眠100毫秒
                Thread.sleep(100);
            } catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            System.out.println("次4.执行Thread.sleep(long)完成之后,["+Thread.currentThread().getName()+"]线程的状态:" + Thread.currentThread().getState());
        },"子线程");
        //获取start()之前的状态
        System.out.println("次1.通过new初始化一个线程,但是还没有start()之前,["+thread.getName()+"]线程的状态:" + thread.getState());
        //启动线程,此时thread还没开始执行,执行权仍在main主线程手里
        thread.start();
        //main主线程休眠50毫秒,从main主线程开始休眠那一刻起,cpu被thread抢走并执行完次2后休眠100毫秒    
        Thread.sleep(50);
        //从main线程开始休眠50毫秒开始,thread也需要休眠100毫秒,所以当main线程休眠到50毫秒瞬间,thread还需要休眠50毫秒,所以thread仍处于sleep状态
        System.out.println("次3.执行Thread.sleep(long)时,["+thread.getName()+"]线程的状态:" + thread.getState());
        //此时main线程再休眠100毫秒,thread还需要再休眠50毫秒,当main线程休眠到50毫秒时,thread已经休眠完毕,此时thread重新抢夺cpu执行权,输出次4,完成次线程,所以当main线程休眠完后,thread肯定已经执行完毕;
        Thread.sleep(100);
        System.out.println("次5.线程执行完毕之后,["+thread.getName()+"]线程的状态:" + thread.getState() + "\n");
    }
}

控制台输出:

1.通过new初始化一个线程,但是还没有start()之前,[子线程]线程的状态:NEW
次2.执行thread.start()之后,[子线程]线程的状态:RUNNABLE
次3.执行Thread.sleep(long)时,[子线程]线程的状态:TIMED_WAITING
次4.执行Thread.sleep(long)完成之后,[子线程]线程的状态:RUNNABLE
次5.线程执行完毕之后,[子线程]线程的状态:TERMINATED
  1. 通过控制台输出可以看出,程序在运行过程中,首先输出次1,此时次线程thread只是通过new初始化了,但还没start,所以thread的状态为NEW
  2. 然后通过thread.start()启动次线程,此时thread还没开始执行,执行权仍在main主线程手里。
  3. 接着main主线程休眠50毫秒,从main主线程开始休眠那一刻起,cpu被thread抢走并执行完次2后休眠100毫秒,此时因为thread已经启动,所以状态为RUNNABLE
  4. 输出次3,因为从main线程开始休眠50毫秒开始,thread也需要休眠100毫秒,所以当main线程休眠到50毫秒瞬间,thread还需要休眠50毫秒,所以thread仍处于sleep状态,此时次线程状态为:TIMED_WAITING
  5. 此时main线程再休眠100毫秒,thread还需要再休眠50毫秒,当main线程休眠到50毫秒时,thread已经休眠完毕,此时thread重新抢夺cpu执行权,输出次4,完成次线程,所以当main线程休眠完后,thread肯定已经执行完毕;
  6. 最后输出次5,这时次线程早已执行完毕,所以状态为TERMINATED

如果觉得结果还不够直观,我们可以尝试着更改主线程的休眠时间,再来测试一下;

	...
	Thread.sleep(50);
	System.out.println("次3.执行Thread.sleep(long)时,["+thread.getName()+"]线程的状态:" + thread.getState());
    //在这里把原本休眠100毫秒改成40毫秒
    Thread.sleep(40);
    System.out.println("次5.线程执行完毕之后,["+thread.getName()+"]线程的状态:" + thread.getState() + "\n");
    ...

此时再观察输出结果

1.通过new初始化一个线程,但是还没有start()之前,[子线程]线程的状态:NEW
次2.执行thread.start()之后,[子线程]线程的状态:RUNNABLE
次3.执行Thread.sleep(long)时,[子线程]线程的状态:TIMED_WAITING
次5.线程执行完毕之后,[子线程]线程的状态:TIMED_WAITING

次4.执行Thread.sleep(long)完成之后,[子线程]线程的状态:RUNNABLE

会发现,在main主线程第二次休眠完时(40毫秒),次线程的100毫秒还没休眠完,所以次5会比次4先输出,而且此时次线程状态为TIMED_WAITING,当次线程100毫秒休眠完后,输出次4,此时此线程还没走完,所以线程状态为RUNNABLE

至此,示例结束;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值