如何让线程停止,有何区别

文章介绍了Java中三种停止线程的方法:自定义中断标识符、使用interrupt方法和弃用的stop方法。自定义中断标识符可能存在响应不及时的问题;interrupt方法通过设置中断标志并让线程自行检查决定何时退出,是推荐的方式;stop方法是不安全的,已被废弃。文章强调了中断线程的最佳实践和线程安全的重要性。
摘要由CSDN通过智能技术生成

Java 中停止线程的实现方法有以下 3 种:

  1. 自定义中断标识符,停止线程。
  2. 使用线程中断方法 interrupt 停止线程。
  3. 使用 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 最新版本中已经被直接移除了,所以不建议使用

创建线程的方式

  1. 继承Thread类实现多线程
  2. 实现Runnable接口
  3. 实现Callable接口
  4. 通过线程池

Android中线程有哪些,原理和特点
Android中的进程与线程
Android 进程间数据共享
线程池的创建方式
Android 之 Handler
HandlerThread 和 Handler 区别

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值