通常来说,会概述为五种,初始状态 可执行状态 运行状态 休眠状态 终止状态
不同的高级语言中,对于线程的不同状态的实现是不同的方式
在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()方法来轮询检测