简单了解 Kotlin 协程

对于线程来说,同步异步是一个行为、阻塞非阻塞是一种状态。协程在某些方面与线程类似,如挂起、切换。但协程是工作在线程之上的。协程的切换可以由程序控制,不需要操作系统调度。

 

launch :创建协程。

runBlocking:最高级协程,也是主协程,launch 创建的协程能够在 runBlocking 中运行,反过来不可以。

fun main() = runBlocking {
    GlobalScope.launch {
        delay(1000L)
        println("world")
    }
    println("hello")
    Thread.sleep(2000L)
}

delay :只能在协程内部使用,它用于挂起协程,不会阻塞线程。

sleep:用来阻塞线程。

job.join() :非阻塞式等待,直到线程结束,不会将当前线程挂起。

 

async :创建子协程,与其他协程并行工作,返回的式 Deferred 对象,Deferred 值是一个非阻塞可取消的 future,它是一个带有结果的 job。

awai :可以去除返回值。

fun main() = runBlocking {
    val async1 = async { }
    val async2 = async { }
    async1.await()
    async2.await()
}

 

重点来了,launch 的源码

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
}

 

CoroutineContext :接收一个可选的 CoroutineContext 参数,是一些元素的集合,主要包括 Job 和 CoroutineDispatcher 元素。可以代表一个协程的场景。默认值EmptyCoroutineContext,表示运行在父协程的上下文中。

CoroutineDispatcher 可以指定协程运行在某一特定线程上、运作在线程池中或者不指定所运行的线程,协程调度器可以分为 Confined Dispatcher 和 Unconfined Dispatcher。

Confined Dispatcher 指定了协程所运行的线程或线程池,挂起函数恢复后协程也是运行在指定的线程或线程池上,如下几类:

Dispatchers.Default :将会获取默认调度器,使用共享的后台线程池

Dispatchers.IO :运行在IO线程中

Dispatchers.Main :运行在主线程中

Unconfined Dispatcher 如:

Dispatchers.Unconfined :协程调度器会在程序运行到第一个挂起点时,在调用者线程中启动。挂起后,它将在挂起函数执行的线程中恢复,恢复的线程完全取决于该挂起函数在哪个线程执行。非受限调度器适合协程不消耗 CPU 时间也不更新任何限于特定线程的共享数据(如 UI)的情境。

 

当然也可以使用 newFixedThreadPoolContext 和 newSingleThreadContext 等创建 context;

 

CoroutineStart 

一般情况下默认 DEFAULT 即可,会根据上下文去启动协程。另外还有有 LAZY 模式,可以延迟启动,注意当协程在执行前被取消后,它不会再执行了。

 

withContext

此函数不会创建新的协程,在指定协程上运行挂起代码块,并挂起该协程直至代码块运行完成。它同样可以指定 CoroutineContext 。

此篇简单介绍下 Kotlin 的协程,深入的源码这里就不详细解释了。

 

最后说下 kotlin 中使用 同步方法

    @Volatile
    private var count: Int = 1;

    @Synchronized
    fun buy() {

    }

    fun buy2() {
        synchronized(this) {
            
        }
    }

也可以使用 Lock 加锁,Kotlin 提供的方法:

public inline fun  Lock.withLock(action: () -> T): T {
    lock()
    try {
        return action()
    } finally {
        unlock()
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Kotlin)