### 写在前面
1.协程“非阻塞式挂起” 你真的弄懂了吗?
2.协程suspend关键字到底有多神奇?
3.协程有了launch,还要async干啥?抱小三?
4.协程真的高大上吗?
#### 1.非阻塞式挂起
阻塞:即程序因耗时操作等原因阻止线程继续运行
非阻塞:即不阻止程序继续运行
挂起:即wait,释放已经获取到的线程资源
非阻塞式挂起:不组织程序运行,还释放了已经获取到的线程资源
那么问题来了,你把资源都释放了我咋继续后续操作?
Are you kid me?
他到底干了啥,有人说是关键字suspend,但是但是,你看下面代码难道执行有区别吗?
```
//测试代码1
GlobalScope.launch(Dispatchers.Main) {
dealprint()
}
//测试代码2
GlobalScope.launch(Dispatchers.Main) {
dealTask()
}
suspend fun dealTask() = withContext(Dispatchers.Default){
Log.i(TAG,"Task:")
}
suspend fun dealprint(){
Log.i(TAG,"print:")
}
```
难道只有代码2才是非阻塞式挂起?代码1不是。
说对了,代码1不是 suspend。dealprint这里的suspend还会提示:
![](https://user-gold-cdn.xitu.io/2020/5/23/17241c5bab975416?w=674&h=123&f=png&s=12837)
提示这里要移除suspend,那就可能是其他的关键点了,关键点就是切换线程
launch withContext async 等
#### 2.suspend
suspend究竟是用来做什么呢?
suspend关键字只是一个提醒,不对两个提醒
提醒1: 我要切换线程了,下边的代码在另一个线程执行
提醒2: 我只能在协程中执行,因为执行完当前suspend方法我要切回到原先的协程继续执行后续操作
#### 3.async
async 同步
上代码
```
suspend fun dealAsyncTask1(): Int {
delay(3000)
Log.i(TAG, "dealAsyncTask1")
return 3
}
suspend fun dealAsyncTask2(): Int {
delay(2000)
Log.i(TAG, "dealAsyncTask2")
return 2
}
//代码一
GlobalScope.launch(Dispatchers.Default) {
Log.i(TAG, "dealAsyncTask--start:")
val one = dealAsyncTask1()
val two = dealAsyncTask2()
Log.i(TAG, "dealAsyncTask:${(one + two)}")
}
//代码二
GlobalScope.launch(Dispatchers.Default) {
Log.i(TAG, "dealAsyncTask--start--async:")
val one = async { dealAsyncTask1() }
val two = async { dealAsyncTask2() }
Log.i(TAG, "dealAsyncTask--async:${(one.await() + two.await())}")
}
```
代码一和代码二的区别是什么,结果是一样的吗?
先上日志:
```
07-08 19:02:08.717 30075-30127/com.matt.mattdemo I/MainActivity: dealAsyncTask--start:
07-08 19:02:08.717 30075-30128/com.matt.mattdemo I/MainActivity: dealAsyncTask--start--async:
07-08 19:02:10.737 30075-30127/com.matt.mattdemo I/MainActivity: dealAsyncTask2
07-08 19:02:11.727 30075-30127/com.matt.mattdemo I/MainActivity: dealAsyncTask1
07-08 19:02:11.727 30075-30127/com.matt.mattdemo I/MainActivity: dealAsyncTask--async:5
07-08 19:02:11.727 30075-30127/com.matt.mattdemo I/MainActivity: dealAsyncTask1
07-08 19:02:13.737 30075-30127/com.matt.mattdemo I/MainActivity: dealAsyncTask2
07-08 19:02:13.737 30075-30127/com.matt.mattdemo I/MainActivity: dealAsyncTask:5
```
可以看到async执行的时间比默认执行短了2s,为啥会短,这就是async的本质,加了async会让代码块程序并发执行,dealAsyncTask2和dealAsyncTask1并发执行,而不是依次执行,好,这个方法太棒了
当然还有更多的async启动模式
```
public enum class CoroutineStart {
DEFAULT,
LAZY,
ATOMIC,
UNDISPATCHED
}
//DEFAULT: 默认值,它会上下文立即调度线程的执行
//LAZY:它不会立即调度协程的执行,而是在需要的时候才会触发执行
//ATOMIC:原子性调度,即不会被取消
//UNDISPATCHED:也会立即调度,直到当前的第一个挂起点,这个后面讨论分发器的时候还会说
```
使用方式
```
async(start = CoroutineStart.LAZY) { dealAsyncTask1() }
```
]
啊,老师,我有问题,我用了这个LAZY后还是依次执行啊,并不是你那样啊?
what??
```
GlobalScope.launch(Dispatchers.Default) {
Log.i(TAG, "dealAsyncTask--start:")
val one = dealAsyncTask1()
val two = dealAsyncTask2()
Log.i(TAG, "dealAsyncTask--normal:${(one + two)}")
}
GlobalScope.launch(Dispatchers.Default) {
Log.i(TAG, "dealAsyncTask--start--async:")
val one = async(start = CoroutineStart.LAZY) { dealAsyncTask1() }
val two = async(start = CoroutineStart.LAZY) { dealAsyncTask2() }
Log.i(TAG, "dealAsyncTask--async:${(one.await() + two.await())}")
}
```
日志:
```
07-08 19:10:42.157 32265-32317/com.matt.mattdemo I/MainActivity: dealAsyncTask--start:
07-08 19:10:42.157 32265-32318/com.matt.mattdemo I/MainActivity: dealAsyncTask--start--async:
07-08 19:10:45.157 32265-32318/com.matt.mattdemo I/MainActivity: dealAsyncTask1
07-08 19:10:45.157 32265-32318/com.matt.mattdemo I/MainActivity: dealAsyncTask1
07-08 19:10:47.157 32265-32321/com.matt.mattdemo I/MainActivity: dealAsyncTask2
07-08 19:10:47.157 32265-32321/com.matt.mattdemo I/MainActivity: dealAsyncTask--normal:5
07-08 19:10:47.167 32265-32321/com.matt.mattdemo I/MainActivity: dealAsyncTask2
07-08 19:10:47.167 32265-32321/com.matt.mattdemo I/MainActivity: dealAsyncTask--async:5
```
呃,这里还有一个问题就是await,LAZY的是按需执行,那么就是需要时才执行了,所以只有等他调用await获取结果的时候,才会执行相应的方法,所以就是依次执行了。
嗯,终于出坑了。
#### 4.协程真的高大上吗
真香,但是香到了什么程度呢?
1.他封装了线程池,旧概念新炒,千万别被官方比线程好多少忽悠了,线程池比线程 也好
2.调度的概念真的很棒,包括语法也很棒,比rxJava的可读可用强太多了
3.效率真的没有显著提升
4.真正的效率Only使用
5.真香
感谢阅读。
网友评论