目录
一个线程在它的声明周期内,需要经历五个状态:
1、新生状态
用new关键字创建了一个线程对象后,该线程就处于新生状态,处于新生状态的线程有自己的内存空间,通过调用线程对象的start()方法进入就绪状态
2、就绪状态
处于就绪状态的线程拥有争夺CPU时间片的权利,等待CPU的调度,就绪状态不是执行状态,一旦获得CPU时间片线程默认调用run方法,有四种原因会导致就绪状态:
2.1:新生状态:线程调用start()方法
2.2:运行状态:CPU分配的时间片用完,返回就绪状态继续等待CPU的调度
2.3:阻塞状态:阻塞解除,进入就绪状态
2.4:运行状态:调用yield()方法线程让步,返回就绪状态等待CPU调度
3、运行状态
当线程分配到CPU时间片时,线程自动调用run()方法,如果给定的时间片消耗完,返回就绪状态继续等待,也可能由于某些原因导致阻塞状态
4、阻塞状态
阻塞状态指的是暂停一个线程,等待某个条件达到,返回就绪状态
5、死亡状态
当一个线程的run方法执行完毕即为死亡状态
线程的使用:
线程休眠:通过调用线程对象的sleep()方法来完成线程的休眠,sleep方法可直接让运行状态的线程转为阻塞状态,等待睡眠结束返回就绪状态抢夺CPU时间片
sleep方法需要传值,参数单位为毫秒。
线程让步:
通过调用yield()方法可将运行状态的线程直接转为就绪状态,但是yield()方法通常无法达到让步的目的,因为调用了yield方法会让线程转为就绪状态抢夺CPU的时间片,但是此线程可能又抢到了CPU时间片,这里通过一张图来解释:
这张图表示线程的运行内容 :
此时我们可以看到while下面的第一句,当i为2时且此时为B线程对象那么让B线程让步,此时如果我们通过启动两个线程对象来看
这张图表示线程的创建以及死亡:
当我启动了两个线程对象时,我们会发现B对象抢夺的时间片比A多,这就说明了让步通常无法达到让步的目的
线程联合:
通过join方法将两个线程联合,join方法会让并发的线程转为串行,联合对象需要等待被联合对象执行结束后,才能继续执行,就像java中的方法一样
我们通过图来讲解:
首先我们创建AThread线程,AThread线程启动BThread线程后,当i==2时A线程与B线程联合,AThread会输出的名字和i
然后我们来看BThread线程,BThread会输出自己的名字和i
我们通过主线程来调用,启动a线程
运行结果是这样的:
总结:联合线程需要等待被联合线程执行结束才能执行
要点:只有线程启动后才能被联合,联合过后的线程转为串行运行
线程是否存活:
通过调用isAlive()方法来判断当前线程为活动状态,活动状态指的是:线程已经被启动且尚未终止,意思就是线程处于就绪状态或者运行状态、阻塞状态就认为线程存活,返回布尔值
线程优先级:
每一个线程都是有优先级的,线程创建后默认优先级为5,优先级范围1~10,从小到大,从低到高
注意:线程优先级并不代表线程优先执行,只是可能被CPU调度的概率更高
int getPriority();//获得线程当前优先级
void setPriority(int newPriority)//设置线程优先级
守护线程:
java线程有两种:
用户线程:就是应用程序里的自定义线程
守护线程:守护线程是一个服务线程,它可以服务任何线程
守护线程的特点:被守护线程死亡,守护线程跟着死亡,相当于寄生关系
通过线程对象.setDaemon(boolean on)来设置线程为守护线程,默认为用户线程false,如需设置为守护线程传递true
要点:在哪个线程对象调用 线程对象.setDaemon(boolean on),那么该守护线程就守护哪个线程