IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]Android实战技巧之四十三:终止一个线程引起的

    lincyang发表于 2015-10-29 17:35:57
    love 0

    这是一道老牌面试题。通常面试官会问你对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();
    }

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



沪ICP备19023445号-2号
友情链接