终止线程的三种方法
1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
2. 使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果)。
3. 使用interrupt方法中断线程。

1、使用退出标志终止线程:

在Activity开启的子线程并不会自动随Activity的destroy而关闭,所以必须手动去关闭子线程或者通过boolean的方式让子线程结束运行。开启的子线程有for循环的要更加注意。

参考:Android学习– 销毁activity时注意关闭线程

package com.lsw;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.cyril.testvolleydemo.R;

public class ThreadDemoActivity extends Activity {
    private static final String TAG = "ThreadDemo";
    private int count = 0;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            Log.e(TAG, Thread.currentThread().getName() + " " + msg.obj);
            setTitle("" + msg.obj);
        }
    };

    boolean stopThread = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //开启子线程
        new Thread(new Runnable() {

            public void run() {
                while (!stopThread) {
                    count++;
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    //虽然Message的构造函数是public的,但是最好是使用Message.obtain( )
                    // 或Handler.obtainMessage( )函数来获取Message对象,
                    // 因为Message的实现中包含了回收再利用的机制,可以提供效率。
                    Message message = mHandler.obtainMessage();
                    message.what = 0;
                    message.obj = count;
                    mHandler.sendMessage(message);
                }
            }
        }).start();
    }

    protected void onDestroy() {
        System.out.println("-----------onDestroy------");
        stopThread = true;
        super.onDestroy();
    };


}

3、使用stop方法可以强行终止正在运行或挂起的线程。

thread.stop();

虽然使用上面的代码可以终止线程,但使用stop方法是很危险的,就象突然关闭计算机电源,而不是按正常程序关机一样,可能会产生不可预料的结果,因此,并不推荐使用stop方法来终止线程。

3、使用interrupt方法终止线程

使用interrupt方法来终端线程可分为两种情况:
(1)线程处于阻塞状态,如使用了sleep方法。
(2)使用while(!isInterrupted()){……}来判断线程是否被中断。
在第一种情况下使用interrupt方法,sleep方法将抛出一个InterruptedException例外,而在第二种情况下线程将直接退出。下面的代码演示了在第一种情况下使用interrupt方法。

参考:

android 停止 终止 Thread 线程的三种方法

有多个线程,如何控制它们执行的先后次序?

方法一:设置线程优先级。

java.lang.Thread 提供了 setPriority(int newPriority) 方法来设置线程的优先级,但线程的优先级是无法保障线程的执行次序的,优先级只是提高了优先级高的线程获取 CPU 资源的概率。也就是说,这个方法不靠谱。

方法二:使用线程合并join。

使用 java.lang.Thread 的 join() 方法。比如有线程 a,现在当前线程想等待 a 执行完之后再往下执行,那就可以使用 a.join()。一旦线程使用了 a.join(),那么当前线程会一直等待 a 消亡之后才会继续执行。什么时候 a 消亡?a 的 run() 方法执行结束了 a 就消亡了。
这个方法可以有效地进行线程调度,但却只能局限于等待一个线程的执行调度。如果要等待 N 个线程的话,显然是无能为力了。而且等待线程必须在被等待线程消亡后才得到继续执行的指令,无法做到两个线程真正意义上的并发,灵活性较差。

join():让一个线程等待 [调用join方法的线程] 运行完成后再继续运行。即它会让其它线程等待该线程运行完成后再运行。

方法三:使用线程通信wait 与 notify 、notifyAll 。

java.lang.Object 提供了可以进行线程间通信的 wait 与 notify 、notifyAll 等方法。每个 Java 对象都有一个隐性的线程锁的概念,通过这个线程锁的概念我们让线程间可以进行通信,各线程不再埋头单干。著名的“生产者-消费者”模型就是基于这个原理实现的。
这个方法也可以有效地进行线程调度,而且也不仅仅局限于等待一个线程的执行调度,具有很大程度上的灵活性。但操作复杂,不易控制容易造成混乱,程序维护起来也不太方便。

yield():暂停当前线程,让同等级优先权的线程运行,假设没有同等级优先权线程则不会起作用。起作用后会让出CPU运行时间,进入就绪状态。

方法四:使用闭锁。

闭锁就像一扇门,在先决条件未达成之前这扇门是闭着的,线程无法通过,先决条件达成之后,闭锁打开,线程就可以继续执行了。java.util.concurrent.CountDownLatch 是一个很实用的闭锁实现,它提供了 countDown() 和 await() 方法达成线程执行队列,这个方法最适合 M 个线程等待 N 个线程执行结束再执行的情况。首先初始化一个 CountDownLatch 对象,比如 CountDownLatch doneSignal = new CountDownLatch(N);该对象具有 N 作为计数阀值,每个被等待线程通过对 doneSignal 对象的持有,使用 countDown() 可以将 doneSignal 的计数阀值减一;每个等待线程通过对 doneSignal 对象的持有,使用 await() 阻塞当前线程,直到 doneSignal 计数阀值减为 0,才继续往下执行。
这个方法也可以有效地进行线程调度,而且比方法三更易于管理,开发者只需控制好 CountDownLatch 即可。但线程执行次序管理相对单一,它只是指出当前等待线程的数量,而且 CountDownLatch 的初始阀值一旦设置就只能递减下去,无法重置。如需递减过程中进行阀值的重置可以参考 java.util.concurrent.CyclicBarrier。
不管如何,CountDownLatch 对于一定条件下的线程队列的达成还是很有用的。对于复杂环境下的线程管理还是卓有成效的。所以熟悉和把握对它的使用还是很有必要的。

参考:

Java 多线程编程之八:多线程的调度