Android如何安全的关闭线程

正常情况下,当线程中的run方法执行完毕后,线程是会自动关闭,不需要我们手动去关闭的。

 如:

new Thread(new Runnable() {
    @Override
    public void run() {
        //执行操作
    }

}).start();

该线程在run方法中的操作执行完毕后,线程会自动关闭。

 

而当run方法中的操作会不断循环执行时如:

new Thread(new Runnable() {
    @Override
    public void run() {
        while (true){
            //执行操作
        }
    }

}).start();

这个线程中run方法会循环执行,并不会中断,所以线程一会一直执行,Android中如果不做终止,即使退出activity也会一直执行,所以我们需要手动终止线程,终止线程的方法:

1.Thread.stop(),该方法是暴力停止线程不推荐使用,已经废弃。

2.使用标记位来停止,如下面例子,如果我们要在activity 销毁时退出线程:

private void stopThread(){
    mThread = new Thread(new Runnable() {
        @Override
        public void run() {
            while (true){
                //执行操作
                if (isStopThread){
                    break;
                }
            }
        }
    });
    mThread.start();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    isStopThread = true;

}

isStopThread变量来判断是否退出线程,如需要退出就直接退出循环,线程终止。

3.使用interrupt方法来停止线程:

private void stopThread(){
    mThread = new Thread(new Runnable() {
        @Override
        public void run() {
            while (true){
                //执行操作
                if (mThread.isInterrupted()){
                    break;
                }
            }
        }
    });
    mThread.start();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    mThread.interrupt();

}

我们使用mThread.interrupt来中断线程,在run方法中使用mThread.isInterrupted()来判断线程是否中断,如果中断责跳出循环,这个标识位的原理其实是一样的。mThread.interrupt并不是强行中断线程,只是给线程设置一个标志,告诉线程我需要中断。

 

接下来我们看下线程阻塞的情况下:

private void stopThread(){
    mThread = new Thread(new Runnable() {
        @Override
        public void run() {
            while (true){
                //执行操作
                Log.e(TAG,"线程执行中..is interrupted = " + mThread.isInterrupted());
                if (mThread.isInterrupted()){
                    break;
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    Log.e(TAG,"出现异常");
                }

            }
        }
    });
    mThread.start();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    Log.e(TAG,"退出activity");
    mThread.interrupt();

}

我们看下log:

 

从log中我们看到退出activity时,线程阻塞抛出了异常,而mThread.isInterrupted()仍然为false,所以线程并没有被中断,这是因为现在进入阻塞时调用mThread.interrupt()方法,会抛出异常同时还会调用interrupted()方法,把isInterrupted恢复称false,所以线程不会被终止,

解决方法很简单我们只要在出现异常中退出循环就可以了:

while (true){
    //执行操作
    Log.e(TAG,"线程执行中..is interrupted = " + mThread.isInterrupted());
    if (mThread.isInterrupted()){
        break;
    }
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
        Log.e(TAG,"出现异常");
        break;
    }

}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值