RunBlocking CoroutineScope SupervisorScope Launch Async CoroutineStart协程启动模式 Job对象和生命周期

协程的作用域构建器

  RunBlocking  

runBlocking是常规函数,会把当前主线程包装成一个主协程,其会阻塞当前线程, 只有当等待其主协程体以及里面的所有子协程执行结束以后,才会让当前线程执行,

  CoroutineScope 
coroutineScope是挂起函数,不会阻塞当前线程。
public actual fun <T> runBlocking(context: CoroutineContext, block: suspend CoroutineScope.() -> T): T {}


public suspend fun <R> coroutineScope(block: suspend CoroutineScope.() -> R): R {}
CoroutineScope与SupervisorScope的区别:
  coroutineScope  一个协程执行失败了,所有其他兄弟协程执行就会中断  (一毁俱毁)
  supervisorScope  一个协程执行失败了,不会影响其他兄弟协程的执行 (一毁不俱毁)
  private fun coroutineScopeTest() {
   //   coroutineScope  一个协程执行失败了,所有其他兄弟协程执行就会中断  (一毁俱毁)
     runBlocking {
         coroutineScope {
             launch {
                 delay(400)
                 LogUtil.e("job1 was executed.")
             }
             launch {
                 delay(200)
                 LogUtil.e("job2 was executed.")
                 throw IllegalArgumentException()
             }
         }
     }
     //只会输出  job2 was executed. 协程1 中断了 不会输出结果
    }

    private fun supervisorScopeTest() {
        //   supervisorScope  一个协程执行失败了,不会影响其他兄弟协程的执行 (一毁不俱毁)
        runBlocking {
            supervisorScope {
                launch {
                    delay(400)
                    LogUtil.e("job1 was executed.")
                }
                launch {
                    delay(200)
                    LogUtil.e("job2 was executed.")
                    throw IllegalArgumentException()
                }
            }
        }
        //会输出  job2 was executed.  job1 was executed.
    }
 

  Launch  

launch 返回一个Job类型,并且不附带任何结果值,没有返回结果值

如果你要在launch函数里执行逻辑,会执行里面的逻辑,但是没有任何返回结果值的(如果你想要有返回结果值 使用Async) 

public fun CoroutineScope.launch():Job

 返回Job类型有个join()函数,是个协程方法,不会阻塞线程。调用此函数意识是 要等当前调用此函数 的协程执行完逻辑后,才会执行其他的子协程

public interface Job : CoroutineContext.Element {
 public suspend fun join()
}

  Async

async返回Deferred类型(集成Job类型  ),(注意我们返回Deferred类型不是我们最总需要的返回结果值) 需要调用await()方法返回我们最终需要的结果值

public fun <T> CoroutineScope.async(): Deferred<T>

返回类型Deferred<T>有个await()函数,是个协程方法,不会阻塞线程。调用此函数意识是 要等当前调用此函数 的协程执行完逻辑后,才会执行其他的子协程,同时其还会返回该子协程执行的逻辑结果值

public interface Deferred<out T> : Job {
 public suspend fun await(): T
 }

  runBlocking {
             val job1: Job = launch {
                 delay(500)
                 LogUtil.e("job1 was executed.")  //执行了launch里的 逻辑: 输出 job1 was executed
                 "方明飞"
             }
                LogUtil.e(job1.toString() ) //没有返回结果值   StandaloneCoroutine{Active}@b57027
                job1.join() //什么意识了? 要等子协程job1执行完后,才会执行后面的子协程job2 job3


          val  job2 :Deferred<String> =async {
              delay(250)
               LogUtil.e("job2 was executed.") //执行了launch里的 逻辑: 输出 job2 was executed.
               val normalData12:NormalData  =get<NormalData>(named("userNameAge"))
                normalData12.userName
          }
              LogUtil.e("${job2.toString()}") //输出 DeferredCoroutine{Active}@a96d2d4
             val job2Result:String  =  job2.await()//什么意识了? 要等子协程job2执行完后,才会执行后面的子协程 job3
                 LogUtil.e(job2Result)//输出结果值  方明飞

         val  job3 :Deferred<Int> =async {
                 delay(100)
                 LogUtil.e("job3 was executed.") //执行了launch里的 逻辑: 输出 job3 was executed.
                 val normalData122:NormalData  =get<NormalData>(named("userNameAge"))
                   normalData122.age
             }
             job3.await()//什么意识了?要等子协程job3执行完后,才会执行主线程
             LogUtil.e("${job3.await()}")//输出结果值  34
             LogUtil.e("${job3.toString()}") //输出  DeferredCoroutine{Completed}@a6c8c7d
         }

 协程启动模式CoroutineStart

协程的启动模式是指定协程启动后的一些行为

 public enum class CoroutineStart {
         DEFAULT,
        LAZY,
        ATOMIC,
          UNDISPATCHED;
        
            }

DEFAULT    创建协程后,立即开始调度执行。 饿汉式启动  launch 调用后,会立即进入待调度状态。  在调度前如果协程被取消,其将直接进入取消状态。

LAZY         只有在需要的情况下运行。 是懒汉式启动 launch 后并不会有任何调度行为,协程体也自然不会进入执行状态,  直到我们需要它执行的时候。

            那什么时候我们需要它执行的时候呢?
             launch 调用后会返回一个 Job 实例,
              调用 job.start(),主动触发协程的调度执行,
              调用 job.join(),隐式的触发协程的调度执行

         asynic 调用后返回一个Deferred<out T>

          调用 Job.await(),才会开始执行调度.

ATOMIC     协程创建后,立即开始调度执行,但在开始运行之前无法取消

UNDISPATCHED  立即在当前线程执行协程体,直到第一个 suspend 调用

public fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
): Job {}
public fun <T> CoroutineScope.async(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> T

): Deferred<T> {}

Job对象和生命周期

对于每一个新创建的协程(通过launch或者async),会返回一个Job实例,该Job实例是协程的唯一标示,并且负责管理协程的生命周期。
Job的生命周期
一个协程任务可以包含一系列Job的生命周期状态:
新创建(New)、活跃(Active)、完成中(Completing)、已完成(Completed)、取消中(Cancelling)和已取消(Cancelled)。
虽然我们无法直接访问这些状态,但是我们可以访问Job的属性:isActive、isCancelled和isCompleted。

如果协程处于活跃状态,协程运行出错或者调用 job.cancel() 都会将当前任务置为取消中 (Cancelling) 状态 (isActive = false, isCancelled = true)。
当所有的子协程都完成后,协程会进入已取消 (Cancelled) 状态,此时 isCompleted = true

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值