线程的五大状态
五大状态分别是:
- 创建状态:刚new出来就是创建状态
- 就绪状态:使用start函数进入就绪状态
- 阻塞状态:代码不能进行下去,CPU被线程独占
- 运行状态:进入运行状态线程才会执行代码
- 死亡状态:线程被释放了
对于五大状态有以下对应关系:
进入这些状态的方法
-
setPriority(int priority):更改线程的优先级。线程也有优先级,但是不是谁优先级高限制性谁,而是优先级大的被执行的概率更高。也就是说,执行谁还是由CPU随机调度,但是优先级大的被调度的可能性更高。
-
static void sleep(long millis):线程休眠,线程将进入休眠状态,参数是毫秒。
-
void join():插入线程,一个线程正在跑。另一个线程使用join函数,那么这个线程插入到正在跑的那个线程之前,并执行。
-
static void yield():暂停当前线程,并执行其他线程。
-
void interrupt():中断线程,最好别用这个方法。
-
boolean isAlive():判断当前线程是否正处于活动状态。
这些方法稍后会做解释。
停止线程
有两种方法停止线程,一个注意点。
- 使用标志位停止线程:在while循环,循环里是线程体,在线程体中设置一个标志位flag。
- 线程自己用完就停 :使用for循环,循环里是线程体。
注意:不要使用stop、destory这些方法停止线程。
其实线程就像并行的程序,执行完自己停止就行。
例如(使用for循环同理):
class MyRunnable implements Runnable{
private boolean flag = true;
public void stop(){
this.flag = false;
}
public void run(){
while(this.flag){
//线程体;
}
}
}
public Do{
public static void main(String[] args){
//打开线程
Thread thread = new Thread(new MyRunnable).start();
//在此处终止线程
thread.stop();
}
}
其实这不算强制系统停止的,而是程序执行完了自然停止的。distory这些方法是直接在运行的时候强制停止用的。
线程休眠
使用sleep方法休眠。使线程进入阻塞状态。
使用时的注意点:
-
sleep的参数为毫秒
-
sleep要返回异常
-
sleep时间到达后,线程重新进入运行状态
-
sleep可以模拟网络延迟,做计时器
-
每个对象都有一个锁,sleep不会释放锁(后续介绍)
-
sleep是类方法,不是成员方法所以使用Thread.sleep调用
注意:sleep可以放在程序的任何地方,因为程序执行后最基本的就有一个主线程,自己产生的也是子线程,所以不论怎样都在线程中,所以sleep可以用在程序的任何地方。线程休眠只是使用了休眠方法的线程休眠其他线程并不休眠,仍在执行。
线程礼让
使用yield方法。
- 线程礼让,让当前执行的线程暂停,但不阻塞。
- 将线程从运行状态进入就绪状态。
- 让CPU重新调度。
- yield是类方法,不是成员方法,使用Thread.yield调用。
示例如图:
并不像sleep那样阻塞,而是直接由运行状态进入就绪状态。(与sleep的区别就是:sleep的CPU不会立即调用A线程,但是yield会使CPU立刻重新调度可能还会选择执行A线程)
线程插队
使用join进行线程插队
- 线程插队的意思是:当某一线程执行了join成员方法后,CPU就专心执行此线程,当此线程执行完毕后再随机调度其他线程。
- 有异常捕获
- 是成员方法,所以在主方法中使用线程对象.join调用。
线程状态观测
使用state方法,是类方发所以使用在线程体中。
八种观测状态:
-
NEW:创建状态
-
RUNNABLE:运行状态
-
BLOCKED:被阻塞状态。等待监视器锁定的线程就处于这种状态中
-
WAITING:正在等待另一线程被CPU调度完成的线程处于这种状态
-
TIMED_WAITING:正在等待另一线程被CPU调度后达到指定等待时间的线程处于这种状态
-
TERMINATED:已退出的线程处于这种状态
线程优先级
线程优先级要求先进行设置优先级,再start启动线程(不可以在启动后更改)
- Java提供一个线程调度器,监控进入就绪状态的所有线程,按照优先级确定哪个线程被执行的概率更大
- 优先级有1——10级,创建好的线程默认5
- 使用**getPriority(num)、setPriority(num)**来查看、更改优先级。它们是成员方法,所以用线程对象.调用。
注意:线程优先级高的线程不一定就一定限制性,只不过是它执行的几率要大一些。
守护线程
还记得之前说的守护线程吗?线程分为三种:主线程、子线程、守护线程。比如Java垃圾回收机制所在的线程就是守护线程(GC线程)。
守护线程的特点:
- 虚拟机必须确保用户线程执行完,但是不必等待守护线程执行完毕。(话句话就是说:当程序终止的时候用户线程必须执行完毕,但是守护线程仍在运行把它强制关闭)
设置守护线程
-
也是在start启动前,将线程设置为守护线程。
-
线程.setDaemon(true),将线程设置为守护线程。(线程默认为false)
-
虚拟机必须确保用户线程执行完,但是不必等待守护线程执行完毕。(话句话就是说:当程序终止的时候用户线程必须执行完毕,但是守护线程仍在运行把它强制关闭)
设置守护线程
- 也是在start启动前,将线程设置为守护线程。
- 线程.setDaemon(true),将线程设置为守护线程。(线程默认为false)