当前位置: 代码迷 >> Android >> Android实战技能之四十三:终止一个线程引起的
  详细解决方案

Android实战技能之四十三:终止一个线程引起的

热度:89   发布时间:2016-04-27 22:29:25.0
Android实战技巧之四十三:终止一个线程引起的

这是一道老牌面试题。通常面试官会问你对Java线程的了解,然后再问此问题。
从理论到实践,这是一条好路子。
线程是操作系统实现多任务的一种方式,可以理解为线程是一个任务的执行单元。比如Android系统中每个App都会有自己的主线程,同时还可以创建worker thread“并行”为我们工作。

Java中创建新线程的方法

Java对线程(Thread)提供了语言级的支持(依托虚拟机吧)。java.lang包下有Thread类和Runnable接口,都可以替你完成创建新线程的工作。
1、extends Thread类

private class NumberCountThread extends Thread {        public void run () {            for (int i = 0;i<1000*1000;++i) {                Log.d(TAG,"count: "+i);                if(mThread.isInterrupted()) {                    Log.d(TAG,"interrupted, return!");                    return;                }                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }    }

2、implements Runnable接口

private class NumberCountRunnable implements Runnable {        public void run() {            int i = 0;            while (true) {                Log.d(TAG, "count: " + i);                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    e.printStackTrace();                }                i++;            }        }    }

3、启动它们

Thread mThread;//Thread        mThread = new NumberCountThread();        mThread.start();//Runnable        mThread = new Thread(new NumberCountRunnable());        mThread.start();

Java线程的运行状态

1、New,新建一个线程
2、Runnable,调用了start方法后线程准备就绪,等待获得CPU的使用权。
3、Running,线程正式运行了,执行run中的代码。
4、Blocked,阻塞状态分几种情况:调用wait方法;线程在获取对象的同步锁;调用sleep或join方法;发出IO请求。
5、Dead,线程执行完毕,或者因其他原因而退出了run方法,就结束了生命周期。

终止一个线程

看线程Dead状态可知,当线程执行完毕后会自动结束生命。这引出常用方法一,线程标记。
在上面两个例子中,我们在循环体中放置一个boolean标记,当其false时,停止循环,即可让线程执行完毕。
比如:

private boolean mThreadFlag = true;private class NumberCountThread implements Runnable {        public void run() {            int i = 0;            while (mThreadFlag) {                Log.d(TAG, "count: " + i);                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    e.printStackTrace();                }                i++;            }        }    }

另一种情况,线程只是在执行单一的耗时的任务,方法一就失效了。而线程中的stop方法是不推荐使用的,那用什么办法才能终止它?
目前使用interrupt方法将其“打断”,进而令其立即退出run方法,进入Dead状态。

与UI线程同步

1、Handler + Message
参考:《Android实战技巧之三十八:Handler使用中可能引发的内存泄漏》

2、View.post方法
在读取asserts中的图片时,用到了线程,那就直接post到主线程吧。

try {    //InputStream inputStream = getResources().openRawResource(R.id.xxx);      InputStream inputStream = assetManager.open("android/xxx.png");    final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);    mMainLayout.post(new Runnable() {        @Override        public void run() {            Log.d(TAG, "set image");            mMainLayout.setBackground(new BitmapDrawable(bitmap));        }    });    inputStream.close();} catch (IOException e) {    e.printStackTrace();}

Activity Destroy后worker thread终止吗?

可以认为主线程与其他线程是两个独立的存在,启动此thread的Activity的销毁并不影响其继续运行,直到任务完成或外界打断。
当然了,整个App退出后,进程(Android中一个进程占用独立的虚拟机)销毁了,线程也就终止了。

isInterrupted()不起作用了?

当使用sleep静态方法让线程睡眠,

    try {        Thread.sleep(1000);    } catch (InterruptedException e) {        e.printStackTrace();    }

只要一调用interrupt方法,就会令其抛出Interrupted Exception,
所以用Thread.currentThread().isInterrupted()作为thread终止标示就不起作用了。

    while (!Thread.currentThread().isInterrupted()) {//do not work anymore        Log.d(TAG, "count: " + i);        try {            Thread.sleep(1000);        } catch (InterruptedException e) {            e.printStackTrace();        }        i++;    }

参考:
http://blog.csdn.net/huang_xw/article/details/7316354
http://www.cnblogs.com/riskyer/p/3263032.html

版权声明:本文为博主原创文章,未经博主允许不得转载。

  相关解决方案