Android的并发编程,即多线程开发,而Android的多线程开发模型也是源于 Java中的多线程模型
所以本篇算是一个基础大纲也会先讲一些Java中的多线程理念,再讲解具体涉及的类,最后深入Android中的并发 场景和实践

并发

什么是并发

举个很简单的栗子,当你一边在 撸撸撸 ,一边在看 小视频 ,同时在做两件事,这就是并发。

咳,年轻人节制啊。

并发的好处

提高资源利用率

当一个任务并没有完全占用系统资源,就可以利用并发来提高资源利用率,同时也能更快地完成任务。

当你的右手在干些什么的时候,左手是不是在没事做呢?那就也用起来呗。
(某次聚会,一名骑马的汉子说自己左右互搏(lu)特厉害)。

在程序任务上更加精简

就拿上一个栗子来说,左手做什么,右手做什么,任务明确分配好,又能同时进行,既提高了效率,逻辑又清晰。

更好的响应程序

这个拿Android客户端举个栗子,上传图片时,当前界面还是正常运转没有卡死,图片也正常上传,既保证了界面被响应,又保证图片可以上传。

并发的风险

并发的代价

  • 需要占用更多的资源。

  • 设计好一个并发程序并不容易。

  • 并发的资源交互问题复杂。

并发的隐患

  • 滥用资源导致系统不稳定

  • 结果与预期不符

  • 出现BUG难以排查

线程篇

进程是什么

就拿Android中的App来说,一般来说一个app就是一个进程,(除了特殊的手段开启了多个进程,这里不深入这个话题,就是一个一对多的关系)。

线程是什么

进程只是一个程序、任务的统称,但是却不能执行任务,真正执行任务的是线程,所以线程是由进程创建的,一个进程可以创建多个线程。

线程可以调度资源等等,在这里只需要了解大致的概念就好,如果要深入可以学习一下 操作系统

进程与线程的关系

人脑就相当于是CPU,想做一件事的时候,这个任务就是一个进程了,需要运用手脚等器官去完成这个任务,而手脚器官就可以理解成一个个线程,去做了不同的事,从而完成任务。

单线程

还是用Android举栗子,当你在手机上操作的时候,这个被称之为UI线程(之后会详解)。而一个最基本的app,不需要复杂的功能时,就只有一个UI线程和我们交互,那么这个app就是个单线程的。一般的程序面向用户的线程就是UI线程,也称之为主线程,单线程程序,其实就是只有一个主线程的程序。

多线程

多个进程可以算是并发,但是我们所说的并发场景,大部分是在一个进程中的,而并发就是由线程完成的,多个线程同时执行任务,就称之为并发。

以下为多线程工作示意图:

Android并发编程引气入门篇_第1张图片" width="640" height="333" style="border:1px solid black;">

多线程并发过程中会遇到的问题

1. 资源共享

A线程要写文件C,B线程也要写文件C,这个时候就好像你拿着两只笔同时往纸上写东西,写出来的是什么自己也不知道。

这个时候我们需要一个类似于 的东西,当C被A在写的时候,B不能写,B要等A写完了才能继续写。

至于这个 到底是什么会在后面继续讲到。

3. 死锁问题

死锁的四个条件是:

  • 禁止抢占:no preemption

  • 持有和等待:hold and wait

  • 互斥:mutual exclusion

  • 循环等待:circular waiting

预防死锁就是至少破坏这四个条件其中一项,即破坏“禁止抢占”、破坏“持有等待”、破坏“资源互斥”和破坏“循环等待”。

举个例子:

A在B那边割包皮,B把A割坏了,A占着B的床位,要B赔钱,B要A让出床位才给钱。双方僵持不下,出现了 互斥 的场面。

线程如何去用

在Java中,线程通常就是指 Thread 这个类,或者实现了 Runnable 的类,其实 Thread 这个类也是实现了 Runnable 接口的,可以看一下 Runnable 接口的代码:

Android并发编程引气入门篇_第2张图片" width="640" height="264" style="border:1px solid black;">

里面就是一个run方法需要被实现。

再看一下 Thread 类的声明:

Android并发编程引气入门篇_第3张图片" width="640" height="317" style="border:1px solid black;">

确实是一个实现了 Runnable 的类。

那么Thread类中拥有 start() 方法,和 run() 方法,下面用 run() 方法直接调用
得到信息:

Android并发编程引气入门篇_第4张图片" width="640" height="307" style="border:1px solid black;">

发现其实和外面的线程是在同一个线程上。

而调用 start() 方法得到的信息是:

Android并发编程引气入门篇_第5张图片" width="640" height="313" style="border:1px solid black;">

发现线程名不一样了,用start会开启一个新的线程,而run还是在当前线程执行。

另外在Java1.5之后,还有Callable、Future和FutureTask,在这里就不详细介绍,还有线程的wait、
yield、sleep等在下一章会一起详细介绍。

线程的优先级

在Java中,线程的优先级有1~10,而默认的是5。1最低,10最高。在Thread类中有三个常量:

  • MIN_PRIORITY = 1

  • NORM_PRIORITY = 5

  • MAX_PRIORITY = 10

在同一个线程池中的线程优先级是相同的。

JVM会根据线程的优先级去抢先调度,然而线程的优先级只能保证抢占资源的概率较大,并不能保障线程的执行顺序,所以不能过于依赖设置线程的优先级。

线程池

频繁地创建和销毁线程会导致性能大幅度降低,这肯定不是你希望的。

线程池的出现,就是为了解决这个问题,根据java中提供不同的线程池机制,有效地提高资源利用率。

直接在代码中创建Thread、Runnable去start或者run容易出现不可预测的问题,在java1.5开始,引入了java.util.concurrent包,其中有个并发的框架: Executor ,使用 ExecutorService 替代直接操作线程类,而 Executors 是用来创建线程池的,内部提供了很多静态方法去创建你想要的线程池,不需要你再手动去创建实现。
看一下关于Executor中的类和接口的大致的成员与关系:

Android并发编程引气入门篇_第6张图片" width="640" height="563" style="border:1px solid black;">

关于这些类如何使用,以及有什么特性,下一章会作介绍。

队列

在java中提到队列肯定会想起 Queue ,而线程队列用的是 BlockingQueue ,这是个接口,在 concurrent 包中有好几个类实现了这个接口。

Android并发编程引气入门篇_第7张图片" width="640" height="210" style="border:1px solid black;">

介绍一下BlockingQueue常用的方法


会异常 返回是否成功 会阻塞 设定等待时间
入队列 add(e) offer(e) put(e) offer(e, timeout, unit)
出队列 remove() poll() take() poll(time, unit)
查看值 element() peek() none none

线程安全

在前面讲过死锁,死锁是由于使用不当引起的一种现象,而这里的锁是人工干预的,让并发按照你的意思走。

在java中的锁有synchonrized、Lock。锁的出现主要是为了解决线程安全问题。

关于 线程的状态 会在下一章讲锁的机制时候再讲,因为线程的状态会影响到锁。

线程安全的集合

因为多线程访问资源可能会造成数据不一致或者数据污染,而某些集合会用一些锁或者同步机制做了处理。

线程安全的集合有:HashTable、SynchronizedCollection、ConcurrentHashMap、Vector等。

线程安不安全的首要前提是在 多线程访问同一个对象 的情况下。

预告

本节中挖的 ,一些没有展开讲的东西,会在下一节中填上。

感谢

《Java并发编程实践》
《Thinking in Java》

baoyongzhang(鲍老师)

欢迎加入QQ群:568863373。

欢迎关注我们的公众号: 魔都三帅 ,欢迎大家来投稿~

Android并发编程引气入门篇_第8张图片" width="430" height="430" style="border:1px solid black;">


可怜可怜我们穷得揭不开锅

Reward

people gave a reward

Submit My Comment Loading

Comment Submitted

更多相关文章

  1. Android性能优化-线程性能优化
  2. Android中的Handler, Looper, MessageQueue和Thread
  3. Android.os.AsyncTask类
  4. Android进程与线程基本知识二
  5. Android(安卓)Handler Message总结
  6. Android异步任务(AsyncTask)的设计思想
  7. android中Handler的初步认识(一)
  8. android程序---->android多线程下载(一)
  9. android 实现主线程、子线程双向通信

随机推荐

  1. AVD(android virtual device)路径设置
  2. Android与Windows Socket通信,TLS双向认证
  3. android menu菜单
  4. Android 全自动js脚本测试 Appium教程—
  5. Android(安卓)WebView系列(一)WebView的基
  6. 浅谈Android系统开发中LOG的使用
  7. phonegap导入工程报错解决办法 错误解析a
  8. Android中抓取手机视频流数据
  9. Android APN的设置问题 默认“已起用数据
  10. Android Camera 模块分析(三)