Java 中停止线程的实现方法有以下 3 种:
- 自定义中断标识符,停止线程。
- 使用线程中断方法 interrupt 停止线程。
- 使用 stop 停止线程
1. 自定义 中断标识符
class MyThread extends Thread {
// 自定义中断标识符
public volatile boolean isMyInterrupt = false;
@Override
public void run() {
// 如果为 true -> 中断执行
while (!isMyInterrupt) {
// to do something
}
}
}
缺点:线程中断的不够及时。因为线程在执行过程中,无法调用 while(!isInterrupt) 来判断线程是否为终止状态,只能在下一轮运行时判断是否要终止当前线程,所以它中断线程不够及时
2. interrupt中断线程
源码:
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // Just to set the interrupt flag
b.interrupt(this);
return;
}
}
interrupt0();
}
通过synchronized关键字修饰。
通过 interrupt 方法可以给执行任务的线程,发送一个中断线程的指令,它并不直接中断线程,而是发送一个中断线程的信号,把是否正在中断线程的主动权交给代码编写者。相比于自定义中断标识符而言,它能更及时的接收到中断指令。
public static void main(String[] args) {
Thread thread = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("thread 执行步骤0:线程将要进入休眠状态");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("thread 执行步骤2:线程接收到中断指令,执行中断操作");
//中断
break;
}
System.out.println("thread 执行步骤1:线程执行了任务");
}
});
thread.start();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主线程:试图终止线程 thread");
//interrupt方法调用-修改中断标识符,中断线程
thread.interrupt();
输出结果:
thread 执行步骤0:线程将要进入休眠状态
主线程:试图终止线程 thread
thread 执行步骤2:线程接收到中断指令,执行中断操作
Thread类中提供了两种方法判断线程是否为停止的。
- this.interrupted():测试当前线程是否已经中断(静态方法)。如果连续调用该方法,则第二次调用将返回false。在api文档中说明interrupted()方法具有清除状态的功能。执行后具有将状态标识清除为false的功能。
- this.isInterrupted():测试线程是否已经中断,但是不能清除状态标识。
线程在接收到中断指令之后,立即中断了线程,相比于上一种自定义中断标识符的方法来说,它能更及时的响应中断线程指令。
3. stop
stop 方法虽然可以停止线程,但是已经不建议使用的废弃方法了,在Thread类源码中可以看见有Deprecated注解修饰。并且方法是不安全的,“@deprecated This method is inherently unsafe.”
stop 源码如下:
@Deprecated(since="1.2")
public final void stop() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
checkAccess();
if (this != Thread.currentThread()) {
security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
}
}
// A zero status value corresponds to "NEW", it can't change to
// not-NEW because we hold the lock.
if (threadStatus != 0) {
resume(); // Wake up thread if it was suspended; no-op otherwise
}
// The VM can handle all thread states
stop0(new ThreadDeath());
}
stop 暴力终止,可能使一些清理性的工作得不到完成。还可能对锁定的内容进行解锁,容易造成数据不同步的问题。
总结
- 自定义中断标识符的停止方法,缺点是不能及时响应中断请求;
- 使用 interrupt 中断线程方法,是发送一个中断信号给线程,它可以及时响应中断,也是最推荐使用的方法;
- stop 方法, 暴力终止线程,但此方法已经是过时的不建议使用的方法,在 Java 最新版本中已经被直接移除了,所以不建议使用
创建线程的方式
- 继承Thread类实现多线程
- 实现Runnable接口
- 实现Callable接口
- 通过线程池
Android中线程有哪些,原理和特点
Android中的进程与线程
Android 进程间数据共享
线程池的创建方式
Android 之 Handler
HandlerThread 和 Handler 区别