yield和sleep
在JDK1.5以前的版本中yield的方法事实上是调用了sleep(0),但是它们之间存在着本质的区别,具体如下
- 1.sleep会导致当前线程暂停指定的时间,没有CPU时间偏的消耗。
- 2.yield只是对CPU调度器的一个提示,如果CPU调度器没有忽略这个提示,它会导致 线程上下文的切换。
- 3.sleep会使线程短暂block,会在给定的时间内释放CPU资源。
- 4.yield会使Running状态的Thread进入Runnable状态,(如果CPU调度器没有忽略 这个提示)
- 5.sleep几乎百分之百地完成了给定时间的休眠,而yield的提示并不能一定担保。
- 6.一个线程的sleep 另一个线程调用interrupt会捕获到中断信号,而yield不会
线程的interrupt
线程的interrupt,是一个非常重要的API,也是经常使用方法,与线程中断相关的API有如下几个
- public void interrupt();
- public static boolean interrupted();
- public boolean isInterrupted();
如下方法的调用会使得当前线程进入阻塞状态,而调用当前线程的interrupt方法,就可以打断阻塞
- 1.Object的wait方法;
- 2.Object的wait(long)方法;
- 3.Object的wait(long,int)方法;
- 4.Thread的sleep(long)方法;
- 5.Thread的sleep(long,int)方法;
- 6.Thread的join方法
- 7.Thread的join(long)方法
- 8.Thread的join(long,int)方法
- 9.InterruptibleChannel的io操作
- 10.Selector的wakeup方法
- 11.其他方法
上述若干方法都会使得当前线程进入阻塞状态,若另外的一个线程调用被阻塞线程的
interrupt方法,则会打断这种阻塞,因此这种方法有时会被称为可中断方法,
-----打断一个线程并不等于该线程的生命周期结束,仅仅是打断了当前线程的阻塞状态
一旦一个线程在阻塞的情况下被打断,都会抛出一个称为interruptedException,这个异常就想一个signal(信号)一样通知当前线程被打断,示例代码如下
public class ThreadInterrupt {
public static void main(String[] args) throws InterruptedException{
Thread thread =new Thread(()->{
try{
TimeUnit.MINUTES.sleep(1);//thread 线程休眠1分钟
}catch (InterruptedException e){
System.out.println("interrupted!!!I can't sleep!");
}
});
thread.start();
TimeUnit.SECONDS.sleep(2);//主线程休眠2秒后执行对thread的打断
thread.interrupt();
//使得thread线程捕捉异常并执行语句 System.out.println("interrupted!!!I can't sleep!");
}
}
isInterrupted
isInterrupted 是 Thread的一个成员方法,用来判断当前线程是否被中断,该方法仅仅是对interrupt标识的一个判断,并不会影响标识的值。
interrupted
interrupted 是一个静态方法,也可以用于判断当前线程是否被中断,同样返回boolean ,但是和成员方法isInterrupted还是有很大的区别的,调用该方法会直接擦除线程的interrupt标识,即将标识设置为false,如果当前线程被打断,第一次调用interrupted方法会返回true,第二次包括以后的调用永远都返回false,除非此期间线程又一次地被打断,
注意事项
打开Thread的源码,isInterrupted和interrupted方法都调用了同一个本地方法
private native boolean isInterrupted(boolean ClearInterrupted)
其中ClearInterrupted用来控制是否擦除线程interrupted的标识。
isInterrupted 方法的源码中该参数为false,表示不想擦除
public boolean isInterrupted(){
return currentThread().isInterrupted(true);
}
而interrupted静态方法找那个该参数则为true,表示想要擦除
public static boolean interrupted(){
return currentThread().isInterrupted(true);
}