Java没有提供任何机制来安全地(抢占式方法)终止线程,虽然Thread.stop和suspend等方法提供了这样的机制,但是由于存在着一些严重的缺陷,因此应该避免使用。但它提供了中断Interruption机制,这是一种协作机制,能够使一个线程终止另一个线程的当前工作。
取消操作的原因:
. 用户请求取消
. 有时间限制的操作
. 应用程序事件
. 错误
. 关闭
结束任务的四种方式:
1. run方法执行结束
2. 使用请求关闭标记(例如boolean开关)
3. 使用中断机制
4. 使用Future退出方法
2. 使用请求关闭标记
当执行到并满足条件是使用return退出run方法
变量需要volatile确保变量多线程环境下的可见性。
-例子待填充,没有执行到判断条件就不会退出,所以不是立即退出的办法。
3. 使用中断机制
优点是相对“请求关闭标记”相应更快一些,但也不是立即关闭线程。
void interrupt() 中断线程。
boolean interrupted() 测试当前线程是否已经中断。
boolean isInterrupted() 测试线程是否已经中断。
InterruptedException异常
程序应该对线程中断作出恰当的响应。
[java]view plaincopy
// 1
Thread thread =newThread("interrupt test") {
publicvoidrun() {
for(;;) {
doXXX();
if(Thread.interrupted()) {
break;
}
}
}
};
thread.start();
// 2
Thread thread =newThread("interrupt test") {
publicvoidrun() {
for(;;) {
try{
doXXX();
}catch(InterruptedException e) {
break;
}catch(Exception e) {
// handle Exception
}
}
}
};
thread.start();
// 3
publicvoidfoo()throwsInterruptedException {
if(Thread.interrupted()) {
thrownewInterruptedException();
}
}
4. 使用Future退出方法
boolean cancel(boolean mayInterruptIfRunning)
试图取消对此任务的执行。
boolean isCancelled()
如果在任务正常完成前将其取消,则返回 true。
*. 处理不可中断的阻塞
*. 采用newTaskFor来封装费标准的取消
之前的任务取消,主要是涉及如何关闭单个线程并且都是由创建单个线程的对象来进行关闭操作,但是如果线程不是由对象自己而是由线程池统一创建的线程该如何处理呢?
1. 使用线程的对象进行关闭 - 当前即使不在对象中创建线程而由线程池创建,这个对象依然可以关闭线程,这点一定要相信程序员的破坏能力,只是使用第2种方式更符合封装原则。
2. 使用线程池统一管理 - 如果是使用ExecutorService创建就交由其进行关闭操作。
2. 使用线程池统一管理(关闭ExecutorService)
void shutdown()
启动一次顺序关闭,执行以前提交的任务,但不接受新任务。如果已经关闭,则调用没有其他作用。
-- 安全关闭方式。
List shutdownNow()
试图停止所有正在执行的活动任务,暂停处理正在等待的任务,并返回等待执行的任务列表。
无法保证能够停止正在处理的活动执行任务,但是会尽力尝试。例如,通过 Thread.interrupt() 来取消典型的实现,所以任何任务无法响应中断都可能永远无法终止。
-- shutdownNow方法的局限性,强制关闭方式。
boolean isShutdown()
boolean isShutdown()如果此执行程序已关闭,则返回 true。
3. “毒丸”对象
只有在生产者消费者的数量都已知的情况下,才可以使用“毒丸”对象。
三、处理非正常的线程终止
Thread.UncaughtExceptionHandler全局的捕获的异常处理,通常在应用中用于异常的统计,收集到这些统计后可以对应用进行异常修复。
1. 关闭钩子
Runtime.getRuntime().addShutdownHook(new Thread()) ;
void addShutdownHook(Thread hook)
注册新的虚拟机来关闭钩子。
2. 守护线程
希望创建一个线程来执行一些辅助工作,但又不希望这个线程阻碍JVM的关闭,可以使用守护线程。
3. 终结器
避免使用终结器finalize
以上就是我推荐给Java开发者们的一面试经典知识。但是这些知识里面并没有太多Java全栈、Java晋阶、JAVA架构之类的题,不是我不推荐,而是希望大家更多的从基本功做起,打好基础,太多复杂的内容一会儿也说不明白。
好了同学们,我能介绍的也都全部介绍完给你们了,如果下获得更多JAVA教学资源,可以选择来我们这里共同交流,群:240448376,很多大神在这里切磋学习,不懂可以直接问,晚上还有大牛免费直播教学。
注:加群要求
1、具有一定工作经验的,面对目前流行的技术不知从何下手,需要突破技术瓶颈的可以加,有些应届生和实习生也可以加。
2、在公司待久了,过得很安逸,但跳槽时面试碰壁。需要在短时间内进修、跳槽拿高薪的可以加。
3、如果没有工作经验,但基础非常扎实,对java工作机制,常用设计思想,常用java开发框架掌握熟练的,可以加。
4、觉得自己很牛B,一般需求都能搞定。但是所学的知识点没有系统化,很难在技术领域继续突破的可以加。
5.阿里Java高级大牛直播讲解知识点,分享知识,多年工作经验的梳理和总结,带着大家全面、科学地建立自己的技术体系和技术认知!
PS:现在主要讲解的内容是(反射原理、枚举原理与应用、注解原理、常用设计模式、正规表达式高级应用、JAVA操作Office原理详解、JAVA图像处理技术,等多个知识点的详解和实战)
6.小号或者小白之类加群一律不给过,谢谢。
最后,每一位读到这里的网友,感谢你们能耐心地看完。觉得对你有帮助可以给个喜欢!希望在成为一名更优秀的Java程序员的道路上,我们可以一起学习、一起进步