kotlin-协程(什么是一个协程)

发布于:2025-05-14 ⋅ 阅读:(8) ⋅ 点赞:(0)
1.什么指一个协程
  
  对于线程来说一个thread就是就是指一个线程,thread为什么成为线程呢?
  因为他实现了对线程的一个抽象管理,可以管理这个线程,启动,可以查看各种信息

那么协程呢?

public fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
): Job {
    val newContext = newCoroutineContext(context)
    val coroutine = if (start.isLazy)
        LazyStandaloneCoroutine(newContext, block) else
        StandaloneCoroutine(newContext, active = true)
    coroutine.start(start, coroutine, block)
    return coroutine
}


可以看到,启动协程的时候创建了一个StandaloneCoroutine的对象,这个对象是Job的实现类,返回了一个job对象。

job有什么方法呢?

job.start()  //启动协程, start: CoroutineStart = CoroutineStart.LAZY
// ,的时候得使用job.start方法才会启动协程,才会调用block的代码
job.cancel() //取效协程
job.isActive  //判读协程的状态
job.join()   //当前的协程阻塞,等待job的协程结束后,再执行当前协程的代码
job.children //子协程的job对象
job.parent //父协程的job对象
job.cancelChildren() //取消所有子协程

那是不是意味着可以把job对象看作一个协程对象呢? 可以也行,但不是全部,job只是管理了协程流程相关的功能,比如开启结束等,但是像协程的名字等是没有的

CoroutineScope是信息最多的,包含可以获取协程的调度器,job等,以及调用launch 和 async去启动一个新的协程,而StandaloneCoroutine也是继承CoroutineScope的

而CoroutineScope里面有一个属性是CoroutineScope,里面全是协程的配置信息

比如:调度器,协程名称,启动模式等

public interface CoroutineScope {
    public val coroutineContext: CoroutineContext
}

协程的父子协程

val parentJob = launch {
    childJob =  launch {
        delay(200)
    }
 }

协程的父子协程是根据job来决定的,在上面的代码中,会把parentJob赋值给childJob的parent属性,会把childJob赋值给parentJob的childJob属性。那怎么相互拿到对方的job呢?

在父协程中启动launch的时候,因为本身就是通过 。CoroutineScope启动的,而CoroutineScope的 coroutineContext 中就可以拿到这个Job。

  runBlocking {
 var childJob:Job?= null
 val parentJob = launch(Dispatchers.IO) {
     childJob =  launch {
         delay(200)
     }
  }
  println("parentJOb${parentJob }")
  println("childJob=${childJob }")
  println("childJOb = parentJOb=${childJob?.parent == parentJob }")
  }

其实看源码可以看到他是复制了父类的coroutineContext的内容

public fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
): Job {
    val newContext = newCoroutineContext(context)
    val coroutine = if (start.isLazy)
        LazyStandaloneCoroutine(newContext, block) else
        StandaloneCoroutine(newContext, active = true)
    coroutine.start(start, coroutine, block)
    return coroutine
}
我们看newCoroutineContext

newCoroutineContext是CoroutineScope的扩展函数,
所以可以拿到当前调用他的launch的CoroutineScope的coroutineContext,和传入的context共同创建一个新的context

public actual fun CoroutineScope.newCoroutineContext(context: CoroutineContext): CoroutineContext {
    val combined = foldCopies(coroutineContext, context, true)
    val debug = if (DEBUG) combined + CoroutineId(COROUTINE_ID.incrementAndGet()) else combined
    return if (combined !== Dispatchers.Default && combined[ContinuationInterceptor] == null)
        debug + Dispatchers.Default else debug
}

 

kotlin 

这里说下我的疑惑点:

第一:parentJob是在  println之前赋值的吗? 

打印结果:

parentJObStandaloneCoroutine{Active}@4b553d26
childJob=StandaloneCoroutine{Active}@69a3d1d
childJOb = parentJOb=true

val parentJob = launch(Dispatchers.IO) {
    childJob =  launch {
        delay(200)
    }
 }

这个代码,虽然指定了Dispatchers.IO,但是只是说把block函数扔进了子线程,但是赋值给parentJob是在主线程的,所以在println之前,但是childJob不一定了

public fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
): Job {
    val newContext = newCoroutineContext(context)
    val coroutine = if (start.isLazy)
        LazyStandaloneCoroutine(newContext, block) else
        StandaloneCoroutine(newContext, active = true)
    coroutine.start(start, coroutine, block)
    return coroutine    //立即返回对象
}

kotlin的父子协程关系就是通过job来绑定的。

假如,我们把childJob的launch传一个job进去,他们就不是父子协程了,这个时候childJob的父协程是传进去的job,注意传进去的job是父job.

fun main() {
  runBlocking {
      CoroutineScope(EmptyCoroutineContext)
 var childJob:Job?= null
 val parentJob = launch(Dispatchers.Default) {
     childJob =  launch(Job()) {
         delay(200)
     }
     delay(300)
  }
  println("parentJOb${parentJob }")
  println("childJob=${childJob }")
  println("childJOb = parentJOb=${childJob?.parent == parentJob }")
  }
}

下面的代码打印结果是什么 

   fun main() {
  runBlocking {
  var job1: Job? =null
      var coroutineScope:CoroutineScope? = null
    val  job =  launch {
          job1= this.coroutineContext[Job]
         coroutineScope = this
         delay(3000)
      }
      delay(100)
      println("coroutineScope === job1=${coroutineScope === job1 }")
      println("job === job1=${job === job1 }")

  }
}

coroutineScope === job1=true
job === job1=true

意思是他们三个其实是一个对象


网站公告

今日签到

点亮在社区的每一天
去签到