java中断机制
2016-06-08 17:27
337 查看
java中断机制
java 提供一个非抢占式的中断机制.它是java语言级提供的一种线程间协作机制.抢占式与非抢占式
抢占式(Preemptive) 指任务之间可以不管互相是否在运行中状态,都可以将抢占对方的CPU计算时间.这种策略可以防止单一任务长时间占用CPU.
非抢占式(Nonpreemptive) 指任务之间不可互相打断运行中状态.Java采用这种策略,使得中断更灵活.(也更麻烦)
中断有什么用?
中断在取消与关闭线程的场景里用的最多.想想不用中断我们是怎样关闭其余线程的.
public class Main { private static volatile boolean cancelled = false; public static void main(String [] args) throws InterruptedException { MyRunnable myRunnable = new MyRunnable(); new Thread(myRunnable).start(); Thread.sleep(3000); System.out.println("Change cancelled to true!"); cancelled = true; } static class MyRunnable implements Runnable{ public void run() { while (!cancelled){ try { doSomething(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("Thread exit!"); } } }
通过一个全局变量作为线程开关标志,子线程定时检查该标志是否关闭来决定子线程的关闭与否.
但是这样的代码会有一个潜在的隐患—-
doSomething()方法有可能是阻塞方法(比如
BlockingQueue.put()或
sleep()),那子线程就有可能永远不会停止.这当然不是我们想要的.怎么办?
中断在这个时候就非常好用!有点类似于这里的
cancelled标志,中断状态通过以下方法来读取和控制:
public class Thread{ //中断线程 public void interrupt() {...} //返回线程的中断状态 public boolean isInterrupted() {...} //清除中断状态,并返回之前的值 public static boolean interrupted() {...} }
而与我们自定义的全局变量标志不同的是,java阻塞库方法(比如方法
BlockingQueue.put()或
sleep())在运行的过程中会检查中断状态(不同与我们在代码中的做法,检查中断是java语言级支持的功能,所以效率和稳定性都很高),万一发现线程被中断,就会结束进程运行并抛出
InterruptedException.
具体说久是如果上面的
doSomething()方法是
Thread.sleep().当我们中断子线程的时候,sleep()会(几乎)立即停止运行并抛出异常!
但如果是非阻塞的方法,如果不显式地处理中断,线程的运行状态并不会发生改变!这个要千万注意! 比如
以下代码
public class Main { private static volatile boolean cancelled = false; public static void main(String [] args) throws InterruptedException { MyRunnable myRunnable = new MyRunnable(); Thread thread = new Thread(myRunnable); thread.start(); Thread.sleep(1000); System.out.println("Change cancelled to true!"); thread.interrupt(); } static class MyRunnable implements Runnable{ public void run() { while (true){ doSomething(); } } private void doSomething(){ waiting(); System.out.println("I am running!"); } private void waiting(){ Long count = 1000000000l; while (count-- > 0); } } }
输出:
子线程并不会对中断做出相应,继续执行.
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树