通常来说,会概述为五种,初始状态 可执行状态 运行状态 休眠状态 终止状态

图片

不同的高级语言中,对于线程的不同状态的实现是不同的方式

在Java中,处于初始状态,就是指在高级语言层面上的被创建了,但并非是真正的被创建了

在可运行状态,就是线程可以分配了CPU,可以真正的运行了

然后是运行状态,就是Cpu分配,进入了运行状态

但是如果调用了一个阻塞的API,或者等待某个时间,就会转换到休眠状态,释放CPU使用前,知道得到新的通知

然后在出现了异常或者执行完成了,就会达到终止状态,不会切换到其他状态,说明生命周期结束了

那么Java中的实现呢?

Java中的线程分为六种状态

1.初始化

2,可运行/运行

3.阻塞

4.无时限等待

5.有时限等待

6.终止

图片

关于状态之间的转换

关于Runnable和Blocked的状态转换

只可能存在于使用Synchronized的时候,由于没获得的Synchronized隐式锁,就从Runnable转到Blocked状态

除此外,使用阻塞式的Api只会让其在操作系统层面上进行阻塞,并不是在Java层面上进行了阻塞

关于Runnable和Waiting状态的转换

通常来说,会出现三种情况

一种情况,使用了wait()方法

第二种情况,使用Thread.join()方法 其中join是一种父子同步的方法,在加入之后,原有线程要等待这个线程执行完后才能再执行

第三种情况,使用LockSupport.park()方法,其中LockSupport(),就是实现并发包中的锁

调用了park就从RUNNABLE导WAITING,调用unpark,又从WAITING到了RUNNABLE

Runnable到TIMED_WAITING的状态转换

1.调用带超时参数的Thread.sleep(long mills)

2.获取Synchronized 隐式锁的线程,调用带超时参数的Object.wait(long timeout)方法

3.带超时参数的Thread.join(long millis)

4.带超时参数的LockSupport.parkNanos(Object blocker,long deadline)

5.带超时参数的LockSupport.parkUnitl(long deadline)

从NEW到RUNNABLE的状态

继承Thraed类,重写Run()方法

实现Runnable接口,重写run()方法

实现Callable接口

使用线程池

从RUNNABLE到TERMINATED状态

到线程终止说明这个方法执行完成了,如果想要手动停止,就需要调用stop() 和 interrupt()方法的

不过stop方法已经被淘汰了

stop因为是直接杀死进程,不会给线程喘息的机会,如果线程持有ReentranLock锁,那么直接杀死会导致锁永久不会被释放

说明其他线程也废掉了

interrupt() 仅仅是通知线程,让线程在执行一些操作后,在进行释放,或者直接无视掉这个线程

最主要的是,在线程A处于WAITING,TIMED_WAITING,其他线程调用线程A的interrupt()方法的时候,线程A返回到Runnable状态,同时触发InterruptedException异常,这就是通过异常的方式让线程得到通知

如果是运行的线程想要检测是否被中断了,就需要isInterrupted()方法来轮询检测

发表评论

邮箱地址不会被公开。 必填项已用*标注