kotlin
coroutines
1. what is Job ?
cancellable
life-cycle
Conceptually, an execution of the job does not produce a result value.
Usually, a job is created in active state (it is created and started). However, coroutine builders that provide an optional
start
parameter create a coroutine in new state when this parameter is set to [CoroutineStart.LAZY]. Such a job can be made active by invoking [start] or [join].
A job is active while the coroutine is working. Failure of the job with exception makes it cancelling. A job can be cancelled it at any time with [cancel] function that forces it to transition to cancelling_ state immediately. The job becomes cancelled when it finishes executing it work.
Job 没有返回值。如果 Job 被创建则开始了它的生命周期,处于 active 状态。如果协程创建器的 start 参数设置为 CoroutineStart.LAZY,job 进入active状态需要通过 start 或者 join 方法。当协程在执行的时候,job 就处于 active 状态。如果 job 出现了异常,则会处于 cancelling。可以用 cancle 方法主动取消 job。job 执行完工作之后就会变成 cancelled 状态
根据上面的描述自己完成下表:
State | [isActive] | [isCompleted] | [isCancelled] |
---|---|---|---|
New (optional initial state) | |||
Active (default initial state) | |||
Completing_ (transient state) | |||
Cancelling (transient state) | |||
Cancelled (final state) | |||
Completed (final state) |
2. Use of Job
job对象常用的方法有三个,叫start
、join
和cancel
。分别对应了协程的启动、切换至当前协程、取消。(以下代码没有特殊说明均在 idea 上运行,也就是基于 JVM,和在 Android 开发中使用协程是有所区别的)
// start 方法
class JobTest {
companion object{
fun start(){
//当启动类型设置成LAZY时,协程不会立即启动,而是手动调用start()后他才会启动。
val job = GlobalScope.launch(Dispatchers.Default, CoroutineStart.LAZY){
print("协程开始了")
}
job.start()
}
}
}
fun main() {
JobTest.start()
}
Q
运行的结果是什么?
什么输出也没有,因为协程的生命周期是随主线程的,主线程已经结束了,所有协程也结束了。
Q
怎样才能得到我们想要的输出结果
在 main 函数里用 thread.sleep 阻塞线程,或者使用 runblocking
fun main() {
runBlocking {
JobTest.start()
}
}
fun main() {
JobTest.start()
Thread.sleep(10000)
}
Q
这里的 Thread.sleep 可以放在 start 的前面吗?
不可以。因为主线程被阻塞了,是不会往下执行的
join()
方法就比较特殊,他是一个suspend
方法。suspend
修饰的方法(或闭包)只能调用被suspend
修饰过的方法(或闭包)。 方法声明如下:
public suspend fun join()
因此,join()
方法只能在协程体内部使用,跟他的功能:切换至当前协程所吻合。
fun joinTest() {
val job1 = GlobalScope.launch(Dispatchers.Default, CoroutineStart.LAZY{
println("hello1")
}
val job2 = GlobalScope.launch(Dispatchers.Default) {
println("hello2")
job1.join()
println("hello3")
}
}
这段代码执行后将会输出
hello2
hello1
Q 思考为啥没有 hello3 ?
Q 如果没有 join 输出结果会怎样?
如果取消 join 运行结果
hello2
hello3
Q
思考为啥没有 hello3 ?
// android 中使用
fun jobJoin() {
val job1 = GlobalScope.launch(Dispatchers.Main, CoroutineStart.LAZY) {
Log.d("join","hello1")
}
val job2 = GlobalScope.launch(Dispatchers.Main) {
Log.d("join","hello2")
job1.join()
Log.d("join","hello3")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
jobJoin()
}
运行结果
answer of table