Android 开发需要了解的线程和并发知识入门

142 阅读4分钟

这是我参与8月更文挑战的第 3 天,活动详情查看:8月更文挑战

最近学习完线程和并发的相关知识。如果只是简单的学习就等于给自己输入了一些知识,不去整理然后输出的话,这些知识不久就会遗忘,所以整理想着整理出文章记录如下。

首先我们看一下线程和进程,用很普遍的两句话就是:

1.进程是程序运行资源分配的最小单位;

2.线程是 CPU 进行调度执行的最小单位,线程又必须依赖于进程而存在。

在安卓开发中一个程序什么都不做的情况下进程内就会有多个线程了,下面是我打印出来的。

thread >>> ReferenceQueueDaemon
thread >>> Binder:5461_3
thread >>> FinalizerDaemon
thread >>> main
thread >>> Jit thread pool worker thread 0
thread >>> RenderThread
thread >>> FinalizerWatchdogDaemon
thread >>> Signal Catcher
thread >>> Binder:5461_2
thread >>> HeapTaskDaemon
thread >>> Profile Saver
thread >>> Binder:5461_1

可见多线程在开发中是必不可少的。CPU 的速度是最快的,内存、磁盘、网络的速度对于 CPU 来说是一个比一个慢。为了能让 CPU 充分跑起来,就需要使用多线程,当然多线程的好处不止这个。CPU 本身采用了时间片轮转机制来保证每个线程都能得到一定时间段的运行,这样就能保证我们的程序正常跑起来了。关于多线程的话题我们后面再说,先说说线程。

线程的启动

放开Thread类的注释我们可以找到启动一个线程的两个方法分别如下。

第一种是继承Thread类,然后调用start方法;

class PrimeThread extends Thread {
}
PrimeThread p = new PrimeThread(143);
p.start();

第二种是实现Runnable接口,然后交给一个Thread来运行。

class PrimeRun implements Runnable {
}
PrimeRun p = new PrimeRun(143);
new Thread(p).start();

当然我们平时开发过程中是不推荐直接新建线程来使用的,一般都是使用线程池。这里面实现Runnable接口后只是对于业务逻辑进行了一些封装,和线程没有任何关系,最后还是需要交给Thread来执行的。

线程的停止

线程中等待run方法里面逻辑执行完成了自然就停止了,如果其中抛出异常也会提交结束。这里需要提到的就是线程的中断,虽然说是中断,但是如果我们自定义线程里面没有对于中断标志位进行处理的话,就算我们线程被其他线程设置中断了,我们线程还是会执行完成的。所以这里的中断只是一个标志位,并不是一个停止的命令。

对于停止等操作是有过期的方法的,比如suspend,resume,stop现在都不推荐使用了,主要是因为不安全。

所以我们在线程处理中需要通过isInterrupted方法来判断是否被中断,如果被中断了就需要停止业务,让进程退出。系统为我们提供的方法都是对中断进行了处理的,比如sleep方法,会抛出中断异常InterruptedException,并且在抛出异常后会将标志位置为false

线程的一些方法和概念

yield 方法

让线程让出 CPU ,但是让出的时间是不可确定的,且不会释放锁资源。所有执行了 yield 方法的线程有可能在进入就绪状态后马上又被操作系统再次执行。

join 方法

将指定的线程加入到当前线程,并等待该线程执行完成后才会继续执行本线程任务。

优先级

线程的优先级是成员变量priority来控制,我们可以自由设置。对于IO操作的线程(会频繁阻塞)我们可以设置高优先级,对于计算线程(占据 CPU 资源)我们可以设置低优先级,保证 CPU 不会被独占。

守护线程

Daemon 线程是一种支持型线程,当虚拟机种只有守护线程时,虚拟机就会退出。

总结

线程的一些介绍就到这里,下一篇我们继续学习多线程的相关知识。