0
点赞
收藏
分享

微信扫一扫

Kotlin协程——协程实现非阻塞任务

如果要实现我们“非阻塞式”的要求,又要怎么办呢?耗时是不得不接受的客观条件,而上面的等待是用于保证顺序性的方法。很明显,我们只能改变等待这个方法。main 线程完成 work1 之后先不急着做 work3,main 线程也不要 “干等” work3,而是先去做点其他的工作,(我们只需要在一个 work流 内的 work1,work2,work3 之间保持顺序,如果其他工作也需要跟这些 work 保持顺序,说明他们也应该在这个工作流内),等 newThread 完成 work2 之后“通知” main 线程,main 线程再在合适的时机继续完成 work3

代码我们可以这样写:

// Thread3.kt
val work = Runnable {
    printlnWithThread("do work 1")
    switchThread3()
}

val otherWork1 = Runnable {
    Thread.sleep(100) // 模拟耗时, 避免main方法中work结束太早,newThread添加work3失败
    printlnWithThread("do work a")
}

val otherWork2 = Runnable {
    printlnWithThread("do work X")
}

// prevent ConcurrentModificationException
val works = ConcurrentLinkedQueue<Runnable>()
fun main() {
    works.addAll(listOf(work, otherWork1, otherWork2))
    works.forEach { it.run() }
}

fun switchThread3() = thread {
    printlnWithThread("do work 2")
    works.add(Runnable { printlnWithThread("do work 3") })
}

运行结果如下:

main: do work 1

Thread-0: do work 2

main: do work a

main: do work X

main: do work 3

在 main方法中,main 线程依次执行完成 work里的 work1, otherWork1, otherWork2,在 work 里启动了一个 newThread 执行 work2,完成 work2 之后 newThread 通过向 main 线程的任务列表添加任务的方式又”切“了一次线程,同时 main 线程正在执行 otherWork1,然后是 otherWork2,最后是 newThread 向 main 线程添加的 work3。从log 可以看出,我们最终完成了我们预期的“切”线程的任务。work 保持了 work1,work2,work3 的顺序工作流,而且也没有通过 main 线程“干等”的方式来保证 subwork 之间的同步性



举报

相关推荐

0 条评论