多线程开发 第2节 线程Thread

更新时间 修改意见
2016-08-02 陈敏

第2节 线程Thread

一个Activity运行在一个主线程上,它不能进行耗时巨大的操作,也不能执行耗时不确定的操作。因此需要在新的线程中进行这些耗时的操作,这种进行耗时操作的线程称作工作线程。

2.1 Thread的简单使用

创建一个新的线程,

  1. 创建一个Runnable,重写它的run()函数,这个函数里用来进行耗时的操作;

  2. Runnable为参数,创建一个Thread,调用Threadstart()方法后,新线程就运行起来了,并执行Runnable中的run()函数;

  3. run()函数执行完毕后,新线程就退出;

在线程执行耗时操作的过程中,有时要取消这个线程的操作,

  1. 最好的办法是在run()函数中增加一个标志位,让工作线程可以检查这个标志位是否被设置上,如果设置上了,就让run()函数,立即返回,

  2. 如果主线程要取消这个线程的工作,修改这个标志位就好了,

2.2 Thread的创建

Thread可以拥有不同的优先级,从低到高有10级。操作系统根据线程的优先级来进行资源调度,优先为优先级高的线程分配CPU资源。在默认情况下,新创建的线程使用默认的优先级NORM_PRIORITY。设置优先级的方式很简单,

可以为线程取名字,当我们用Android Monitor工具调试应用的时候,就能看到创建线程时它的名字,方便我们观察、调试程序,

有时,一个应用会同时启动多个Thread,在创建它们的时候可以为它们设置ThreadGroup参数,将它们分成一组,便于对这些线程进行统一的管理。比如,中断这个组里所有线程的运行;

2.3 Thread的停止

Thread的停止就是指这个线程的退出。线程的退出原因无外乎两种,

  1. 工作线程的工作完成了;
  2. 工作线程虽然正在进行耗时工作,但是被取消了,要提前结束;

2.3.1 正常退出

Runnable中的run()函数执行完并返回后,当前的Thread就退出了。

2.3.2 使用标志位

  1. run()函数中增加一个标志位,工作线程会随时检查这个标志位是否被设置上,如果设置上了,就让run()函数,立即返回,

  2. 如果主线程要取消这个线程的工作,修改这个标志位就好了,

2.3.3 使用interrupt()方法

interrupt()是线程提供的一个标准的线程退出方法,如果当前的工作线程正被Object.waitThread.joinThread.sleep阻塞,那么使用thread.interrupt()之后,正在运行的线程会抛出一个InterruptedException异常,

不过interrupt()方法并不是万能的,不是所有阻塞情况下都能够让线程立即退出。

例如当该线程正在用ServerSocketaccept()方法等待连接的时候,即使调用了这个工作线程的interrupt()方法,该线程还是不会抛出异常的。

它只对Object.waitThread.joinThread.sleep这几种阻塞有效果。对于网络读取数据时阻塞状态解除是没有效果的。

*对于网络读取数据时造成的阻塞,我们会在以后相应的章节详细介绍解决方法。

2.4 线程之间的同步

线程间的同步就是指线程A执行到一个地方的时候,停了下来,等待线程B的执行结果;等线程B执行出结果后,线程A才能继续执行。

2.4.1 join()方法

最常见的就是主线程的执行,依赖于工作线程的退出。

主线程启动了工作线程以后,有时候需要等到工作线程结束以后再进行接下来的操作。

例如一个Activity,在onCreate()的时候创建了一个工作线程Thread B;后来在用户的要求下,Activity退出,要被销毁了;销毁Activity时,主线程要等到Thread B执行完了才能继续接着进行剩下的清理工作,那么Activity可以在它的onDestroy()函数中可以使用join()方法,等待子线程的结束,

join()方法,会一直处于阻塞状态,直到线程B退出。

onDestroy()中使用join()有天生的缺点:不能在主线程中进行耗时不可控的操作(例如这里等待工作线程执行完毕),万一工作线程的退出花费了很长的时间,那就有问题了。这里的场景只是用来举一个例子而已。

2.4.2 wait()方法

利用Objectwait()方法实现线程间的同步,需要线程之间共享一个“锁”-Object对象。

当主线程A执行到一个阶段的时候,如果要等待线程B,就把锁置于等待状态,

此时,线程A就出于阻塞的状态,不能往下执行了。

线程B继续它的运行,当它执行到一个阶段的时候,将锁设置成放行状态,

此时,线程A的阻塞状态解除,可以继续往下执行了。


/**************************************************************************/
* 版权声明
* 本教程只在CSDN安豆网发布,其他网站出现本教程均属侵权。
/
**************************************************************************/