java停止线程的方法
停止一个线程通常意味着在线程处理任务完成之前停掉正在做的操作,也就是放弃当前的操作。
在 Java 中有以下 3 种方法可以终止正在运行的线程:
线程正常退出,也就是当 run() 方法完成后自动退出。
使用 stop() 方法强行终止线程,但是不推荐使用这个方法,该方法已被弃用。
使用 interrupt 方法中断线程。
一、线程正常执行完毕后线程自动退出
二、使用stop()退出
在java中的Thread类中提供了一系列方法 start()、stop()、resume()、suspend()、destory()等方法来管理线程,除了start()其它方法都已经过时
jdk中有一个文档专门解释为什么弃用这些方法:https://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html
为什么停止使用stop方法?
1、stop()它本质上是不安全的。停止线程会使其解锁所有已锁定的监视器
2、调用 stop() 方法会立刻停止 run() 方法中剩余的全部工作,包括在 catch 或 finally 语句中的,并抛出ThreadDeath异常(通常情况下此异常不需要显示的捕获),因此可能会导致一些清理性的工作的得不到完成,如文件,数据库等的关闭
3、调用 stop() 方法会立即释放该线程所持有的所有的锁,导致数据得不到同步,出现数据不一致的问题。
三、使用interrupt()退出
使用stop方法停止线程不安全,运行时停止线程,只能使用interrupt();
注意:interrupt()并不是马上停止线程,而是仅仅给这个线程打一个停止标记,需要使用isInterrupted()来判断线程是否中断;
public void platfromLogin(){
if(!loginThread.isAlive()){
if(loginThread.getState()== Thread.State.NEW||loginThread.getState()== Thread.State.TERMINATED){
loginThread =new Thread(()->platformLoginThread());
loginThread.start();
}
}
}
private void platformLoginThread(){
try{
int num = 0;
while (num <= 2){
if(platformReady||loginThread.isInterrupted()){
return;
}
num++;
log.info("发送企业登陆第{}次",num );
this.sendPlatformLogin();
Thread.sleep(60*1000);
}
}catch (Exception arg){
log.error("发送企业认证时出现问题:",arg);
}
}
public void cancelPlatfromLogin(){
if (this.loginThread == null){
return;
}
if(!this.loginThread.isAlive()) {
this.loginThread=null;
return;
}
try {
this.loginThread.interrupt();
this.loginThread = null;
} catch (Exception ex) {
log.info("中断登录线程...非预期错误:",ex);
}
}
使用loginThread.isInterrupted()可以感知到当前线程是否中断,
所以如果希望线程 t 在中断后停止,就必须先判断是否被中断,并为它增加相应的中断处理代码:
但是在遇到 sleep() 或者 wait() 这样的操作,我们只能通过中断来处理了。
Thread.sleep() 方法会抛出一个 InterruptedException 异常,当线程被 sleep() 休眠时,如果被中断,这会就抛出这个异常。
(注意:Thread.sleep() 方法由于中断而抛出的异常,是会清除中断标记的。)