第三十七节 协程二

2018-06-03  本文已影响6人  最美下雨天

看几张图


image.png
image.png
image.png
image.png
image.png

协程原理
• 可以把耗时任务先挂起
• 等时间到了再从线程池中取出空闲的线程执行
• 但是必须是挂起函数才能挂起

挂起函数

关键字suspend

协程的取消

import kotlinx.coroutines.experimental.delay
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.runBlocking

fun main(args: Array<String>)= runBlocking {
    val job = launch {
        (1..10).forEach {
            println("打印$it")
            delay(500L)
        }
    }
    //定时3秒钟,调用cancel方法取消协程
    delay(3000L)
    //取消协程
    job.cancel()

    job.join()
}

输出:


image.png

协程的定时任务

import kotlinx.coroutines.experimental.delay
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.runBlocking
import kotlinx.coroutines.experimental.withTimeout

fun main(args: Array<String>) = runBlocking {
    val job = launch {
        withTimeout(2000L) {
            (1..10).forEach {
                println("打印$it")
                delay(500L)
            }
        }
    }

    job.join()
}

输出:


image.png

取消失效

fun main(args: Array<String>) = runBlocking{
    val job = launch {
        (1..10).forEach {
            println("打印$it")
            Thread.sleep(500L)
        }
    }
    //定时2秒钟  停止协程
    delay(2000L)
    //取消协程
    job.cancel()//取消挂起  Thread.sleep是阻塞式函数,不是挂起函数

    job.join()
}

输出:


image.png

协程的状态

import kotlinx.coroutines.experimental.delay
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.runBlocking

fun main(args: Array<String>)= runBlocking {
    val job = launch {
        (1..10).forEach {
            println("打印$it")
            delay(500L)
        }
    }
    //定时3秒钟  停止协程
    delay(3000L)
    //协程状态
    println("取消之前${job.isActive}")

    //取消协程
    job.cancel()

    println("取消之后${job.isActive}")


    job.join()
}

输出:


image.png

协程的返回值

import kotlinx.coroutines.experimental.async
import kotlinx.coroutines.experimental.delay
import kotlinx.coroutines.experimental.runBlocking

/**
 * 第一中启动协程方式:launch 没有返回值
 * 第二种启动协程方式:async 需要返回值就是用async
 */
fun main(args: Array<String>) = runBlocking{
    //Deferred 是job的子类
    val job1 = async { job1() }
    val job2 = async { job2() }
    val result1 = job1.await()//执行完协程之后才能获取到数据
    val result2 = job2.await()
    println(result1)
    println(result2)

}
suspend fun job1():String{
    println("开始执行job1")
    delay(1000L)
    println("执行了job1")
    return "job1"
}
suspend fun job2():String{
    println("开始执行job2")
    delay(1000L)
    println("执行了job2")
    return "job2"
}

输出:


image.png

协程的上下文

import kotlinx.coroutines.experimental.*

fun main(args: Array<String>)= runBlocking {
    //第一个代表协程上下文 指定协程代码在哪个线程池中运行 默认是通过Commpool实现的
    val job1 = launch {
        println("协程执行")
    }
    val job2 = launch(CommonPool) {
        println("协程执行")
    }
    val job3 = launch(Unconfined) {//运行在主线程中
        println("协程执行")
    }
    val job4 = launch(coroutineContext) {//运行在父协程的上下文中 当前运行在主线程中
        println("协程执行")
    }
    val job5 = launch(newFixedThreadPoolContext(5,"新线程")) {//自定义线程池执行
        println("协程执行")
    }
    job1.join()
    job2.join()
}

看结果额,很重要

image.png

我们以前在使用线程时,线程在执行过程中发送阻塞,再次执行时是在同一个线程,而协程不同,不一定是不是在同一个线程

上一篇 下一篇

猜你喜欢

热点阅读