一、生命周期:新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)、死亡(Dead)
1. 新建
1)当程序使用new关键字创建了一个线程之后,该线程就处于新建状态。
2)和其它Java对象一样,由Java虚拟机为其分配内存,并初始化其成员变量的值
(没有表现出任何线程的动态特征,程序也不会执行线程的线程执行体)
2. 就绪
1)线程对象调用start()方法之后,该线程处于就绪状态
(线程已经被启动,正在等待被分配给CPU时间片,也就是说此时线程正在就绪队列中排队等候得到CPU资源)
2)Java虚拟机为其创建方法调用栈、程序计数器。
对于新建状态的线程调用start()方法,否则将引发异常,若直接调用run()方法,则不会启动线程,而是把run()方法当成一个普通方法执行
(处于这个状态的线程并没有开始运行,只是表示该线程可以运行了)
3. 运行 线程获得CPU资源正在执行任务(run()方法),此时除非此线程自动放弃CPU资源或者有优先级更高的线程进入,线程将一直运行到结束。
4. 阻塞
由于某种原因导致正在运行的线程让出CPU并暂停自己的执行,即进入堵塞状态
正在睡眠:用sleep(long t)方法可使线程进入睡眠方式。一个睡眠着的线程在指定的时间过去可进入就绪状态。
正在等待:调用wait()方法。(调用motify()方法回到就绪状态)
被另一个线程所阻塞:调用suspend()方法。(调用resume()方法恢复)
5. 死亡当线程执行完毕或被其它线程杀死,线程就进入死亡状态
线程结束的方式有三种,结束后就是死亡状态
1)自然终止:run()或call()方法执行完成,线程正常结束
2)异常终止:线程抛出一个未捕获的Exception或Error
3)异常终止:直接调用该线程的stop()方法来结束该线程——该方法会导致死锁,不推荐
判断线程是否死亡
调用线程对象的isAlive()方法,当线程处于就绪、运行、阻塞三种状态时,返回true;处于新建、死亡时,返回false
PS:
1)一旦子线程启动,它便拥有了和主线程一样的地位,且不受主线程影响。(当主线程结束时,子线程不受影响)
2)start()方法报异常:对死亡状态的线程调用该方法,对新建状态的线程调用两次该方法
二、常用方法
void run() 创建该类的子类时必须实现的方法
void start() 开启线程的方法
static void sleep(long t) 释放CPU的执行权,不释放锁
static void sleep(long millis,int nanos)
final void wait()释放CPU的执行权,释放锁
final void notify()
static void yied()可以对当前线程进行临时暂停(让线程将资源释放出来)
三、结束线程原理
(1)结束线程原理:就是让run方法结束。而run方法中通常会定义循环结构,所以只要控制住循环即可
(2)方法----可以boolean标记的形式完成,只要在某一情况下将标记改变,让循环停止即可让线程结束
(3)public final void join()//让线程加入执行,执行某一线程join方法的线程会被冻结,等待某一线程执行结束,该线程才会恢复到可运行状态
四、线程调度:
线程的何时运行,取决于线程调度器的调度,线程调度的细节取决于底层平台所采用的策略。
1)抢占式策略:系统会给每个可执行的线程一小段时间来处理任务;当该时间用完后,系统就会剥夺该线程所占用的资源,在选择下一个线程时,系统会考虑线程优先级
2)协作式策略:只有当一个线程调用了它的sleep()或yield()方法后才会放弃所占用的资源,也就是必须由该线程主动放弃所占用的资源