一般我们需要异步操作的时候,都是通过多线程来实现的,但是线程的创建和开启是个耗性能的操作,开少量的线程没有问题,可是线程多了就有问题了,而且线程还会有各种数据同步的问题。 协程作为一个轻量级的线程,可以完美解决这些问题。你试下开100万个线程?不死机我吃电脑。但是你开100万个协程,那是分分钟的事。 这里只说android和kotlin中的使用。
输出: 我是一个协程 主线程退出了
输出: 协程开始 协程结束 主线程退出了
输出: 开始 结束 我是suspend方法打印的
输出: 开始 in launch 结束
Job.cancel 实际上是抛出异常,会直接中断执行。
fun main() { runBlocking { println("开始") val job = launch { try { var i = 1 while (isActive) { print(i++) delay(500L) } } finally { println("\n异常退出") } } delay(1300L) job.cancelAndJoin()// cancel实质上是抛出异常,所以会直接停止,而不会等到delay完后再停止 println("结束") } }输出: 开始 123 异常退出 结束
Timeout实际上也是抛出异常。
fun main() { runBlocking { println("开始") try { val result = withTimeout(1300) { repeat(10) { print(it) delay(500) } "正常完成,没有Timeout" } println("\n结束 result=$result") } catch (e: TimeoutCancellationException) { println("\n结束 Timeout了") } } }输出: 开始 012 结束 Timeout了
Channel相当于BlockingQueue
fun main() { runBlocking { println("开始") val channel = Channel<Int>() launch { for (x in 1..5) channel.send(x * x) channel.close() } for (y in channel) print("$y ") println("\n结束") } }输出: 开始 1 4 9 16 25 结束
如果想要 async 不自行执行,加上 CoroutineStart.LAZY 即可,然后 async 将会等待调用 start 或者 await 后才会执行,如下:
fun main() { runBlocking { println("开始") val d = async(start = CoroutineStart.LAZY) { println("async start...") delay(1000) println("async end") 999 } d.start() println("d=${d.await()}") println("结束") } }输出: 开始 async start… async end d=999 结束
输出: GlobalScope.launch DefaultDispatcher-worker-1 Dispatchers.Default DefaultDispatcher-worker-3 Dispatchers.IO DefaultDispatcher-worker-3 Dispatchers.Unconfined main launch main
https://kotlinlang.org/docs/reference/coroutines/coroutines-guide.html https://github.com/Kotlin/kotlinx.coroutines