一、线程休眠
让当前线程暂停执行,从运行状态进入阻塞状态,将 CPU 资源让给其他线程的调度方式,通过 sleep() 来实现。
sleep(long millis),调用时需要传入休眠时间,单位为豪秒。
注意:
在外部调用需要注意,休眠一定要放在启动之前。直接通过静态方式调用 sleep 方法可以使主线程休眠。
sleep 是静态本地方法,可以通过类调用,也可以通过对象调用,方法定义抛出 InterruptedException(InterruptedException 继承 Exception,外部调用时必须手动处理异常)。
//普通线程休眠
public class MyThread extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0;i<10;i++) {
if(i == 5) {
try {
sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(i+"---------MyThread");
}
}
}
------------------------------------------------------------------------
//主线程休眠
public class Test2 {
public static void main(String[] args) {
for(int i=0;i<10;i++) {
if(i == 5) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(i+"+++++Test2+++++");
}
}
}
二、线程合并
合并是指将指定的某个线程加入到当前线程中,合并为一个线程,由两个线程交替执行变成一个线程中的两个自线程顺序执行,通过调用join()方法实现。
线程甲和线程乙,线程甲执行到某个时间点的时候调用线程乙的 join方法,则表示从当前时间点开始 CPU 资源被线程乙独占,线程甲进入阻塞状态,直到线程乙执行完毕,线程甲进入就绪状态,等待获取 CPU 资源进入运行状态。
join 方法的两种使用方式:
1、join() 表示乙线程执行完毕之后才能执行其他线程
2、join(long millis) 表示乙线程执行 millis 毫秒之后,无论是否执行完毕,其他线程都可以和它争夺 CPU 资源。
四、线程礼让
线程礼让是指在某个特定的时间点,让线程暂停抢占 CPU 资源的行为,运行状态/就绪状态—》阻塞状态,将 CPU 资源让给其他线程来使用,通过 yield 方法实现。
假如线程甲和线程乙在交替执行,某个时间点线程甲做出了礼让,所以在这个时间节点线程乙拥有了 CPU 资源,执行业务逻辑,但不代表线程甲一直暂停执行。
线程甲只是在特定的时间节点礼让,过了时间节点,线程甲再次进入就绪状态,和线程乙争夺 CPU 资源。
五、线程中断
线程停止运行的几种情况:
1、线程执行完毕自动停止(被动停止)
2、线程执行过程中遇到错误抛出异常并停止(被动停止)
3、线程执行过程中根据需求手动停止(主动停止)
Java 中实现线程中断有如下几个常用方法:
public void stop()
public void interrupt()
public boolean isInterrupted()
stop 方法在新版本的 JDK 已经不推荐使用,重点关注后两个方法(比较粗暴,例如关电脑直接拔电源)。
interrupt 是一个实例方法,当一个线程对象调用该方法时,表示中断当前线程对象。
每个线程对象都是通过一个标志位来判断当前是否为中断状态。
isInterrupted函数就是用来获取当前线程对象的标志位:
1、true 表示清除了标志位,当前线程已经中断。
2、false 表示没有清除标志位,当前对象没有中断。
当一个线程对象处于不同的状态时,中断机制也是不同的。
创建状态:实例化线程对象,不启动。