关闭线程的的三种方法

Java 之前有个api函数可以直接关闭线程, stop(), 后来, 取消了. 其替代的方式主要有两种:

1. 自己加入一个成员变量, 我们在程序的循环里面, 轮流的去检查这个变量,  变量变化时,就会退出这个线程. 代码示例如下
package  com.test;

public   class  StopThread  extends  Thread {

    
private   boolean  _run  =   true ;
    
public   void  stopThread( boolean  run) {
        
this ._run  =   ! run;
    }
    
    @Override
    
public   void  run() {
        
while (_run) {
            
// /
            
// 数据处理
             // /
        }
        
// super.run();
    }

    
public   static   void  main(String[] args) {
        StopThread thread 
=   new  StopThread();
        thread.start();
        
try  {
            Thread.sleep(
1000 );
        } 
catch  (InterruptedException e) {
            e.printStackTrace();
        }
        
// 停止线程
        thread.stopThread( true );
    }

    
}
2. 方法1 虽然可以可以处理好, 不过, 在有阻塞线程的语句的时候往往不能处理好. 比如, 设计到Socket的阻塞语句. 虽然java有提供异步io但是异步io是在程序里不断去查询有没有消息的, 所以耗电量可想而知, 对手机这种设备来说往往不适用.
那么阻塞的语句,怎么终止线程呢?
Java虽然deprecate了一个stop,但是,提供了interrupt(),这个方法是安全的.  这个中断方法可以将阻塞的线程唤醒过来, 但是注意 他不能将非阻塞的线程中断. 中断的同时,会抛出一个异常InterruptedException. 幸运的是, SocketChannel.connect() .read() 阻塞方法都会接受中断,ClosedByInterruptException.
这时我们不轮询变量了, 轮询当前线程是否被中断, 代码
package  com.test;

public   class  StopThread  extends  Thread {


    @Override
    
public   void  run() {
        
try  {
            System.out.println(
" start " );
            
while ( ! this .isInterrupted()) {
                
// /
                
// 数据处理
                 // /
                
                
            }
        } 
catch  (Exception e) {
            e.printStackTrace();
        }
        System.out.println(
" stop " );
        
// super.run();
    }

    
public   static   void  main(String[] args) {
        StopThread thread 
=   new  StopThread();
        thread.start();
        
try  {
            Thread.sleep(
1000 );
        } 
catch  (InterruptedException e) {
            e.printStackTrace();
        }
        
        thread.interrupt();
        System.out.println(
" interrupt " );
    }
    
    
}
3. Android 在自己的Api中加入了,Process类, 这个类可以直接终结进程, 也就是当前线程所在的JVM. 
final static void killProcess(int pid)  其中,pid, 可以通过Process.mypid() 获取, 但这样终结的是整个程序, 不是我们所想要的.
==================================================分割线==========================================
如果该线 程处在不可中断状态下,就是没有调用上述api,那么java只是设置一下该线程的interrupt状态,其他事情都不会发生,如果该线程之后会调用行 数阻塞API,那到时候线程会马会上跳出,并抛出InterruptedException,接下来的事情就跟第一种状况一致了。如果不会调用阻塞 API,那么这个线程就会一直执行下去。除非你就是要实现这样的线程,一般高性能的代码中肯定会有wait(),yield()之类出让cpu的函数,不 会发生后者的情况。
            readCacheThread = new Thread(){
                public void run() {
                   
                    try {
                        Method getPackageSizeInfo = pm.getClass().getMethod(
                                "getPackageSizeInfo", String.class,
                                IPackageStatsObserver.class);
                        for (AppInfoItem item : installedApp) {//个人应用
                            sleep(1);//interrupt后会抛异常,这样就可以提前结束线程
                            getPackageSizeInfo.invoke(pm, item.packageName, pkgsizeobserver);
                        }
                        for (AppInfoItem item : systemApp) {//系统应用
                            sleep(1);
                            getPackageSizeInfo.invoke(pm, item.packageName, pkgsizeobserver);
                        }
                       
                    } catch (Exception e) {
                        // TODO: handle exception
                        e.printStackTrace();
                        Log.e("qqqqqqqqqqqqq", "sleep over");
                        return;
                    }
                   
                };
            };
            readCacheThread.start();
在需要中断线程的地方调用:
            if(readCacheThread != null && readCacheThread.isAlive()){
                //Log.e("readCacheThread", "thread interrupt_1");
                readCacheThread.interrupt();
                //Log.e("status", ""+readCacheThread.isInterrupted());
            }
(用判断readCacheThread.isInterrupted()方法会失败,因为老是返回false,不知道为什么。所以只能用sleep()然后捕获异常再退出)。
这样便可提前退出一个线程。

转载于:https://www.cnblogs.com/Greenwood/archive/2011/07/26/2117722.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值