Android 协程 cpu密集型任务的取消

Posted 安果移不动

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 协程 cpu密集型任务的取消相关的知识,希望对你有一定的参考价值。

 /**
     * 密集型的任务取消
     */
    @Test
    fun `test cancel cpu task by isActive`() = runBlocking<Unit> 
        val startTime = System.currentTimeMillis()
        val job = launch(Dispatchers.Default) 
            var nexPrintTime = startTime
            var i = 0
            while (i < 5 && isActive) 
                if (System.currentTimeMillis() >= nexPrintTime) 
                    println("job:I'm sleeping $i++...")
                    nexPrintTime += 500
                
            


        
        delay(1300)
        println("main:I'm tired of waiting")
        job.cancelAndJoin()
        println("main:Now i can quit.")


    

如果不加 && isActive

会无法取消掉 把四次结果都打印出来。。

也可以是使用这个方法

    /**
     * 密集型的任务取消
     */
    @Test
    fun `test cancel cpu task by enSureActive`() = runBlocking<Unit> 
        val startTime = System.currentTimeMillis()
        val job = launch(Dispatchers.Default) 
            var nexPrintTime = startTime
            var i = 0
            while (i < 5) 
                ensureActive()
                if (System.currentTimeMillis() >= nexPrintTime) 
                    println("job:I'm sleeping $i++...")
                    nexPrintTime += 500
                
            


        
        delay(1300)
        println("main:I'm tired of waiting")
        job.cancelAndJoin()
        println("main:Now i can quit.")

    

    ensureActive() 抛出Cancel的那个异常来退出循环

还有一种方式通过yield

 /**
     * 密集型的任务取消
     */
    @Test
    fun `test cancel cpu task by yield`() = runBlocking<Unit> 
        val startTime = System.currentTimeMillis()
        val job = launch(Dispatchers.Default) 
            var nexPrintTime = startTime
            var i = 0
            while (i < 5) 
                yield()
                if (System.currentTimeMillis() >= nexPrintTime) 
                    println("job:I'm sleeping $i++...")
                    nexPrintTime += 500
                
            


        
        delay(1300)
        println("main:I'm tired of waiting")
        job.cancelAndJoin()
        println("main:Now i can quit.")

    

yield()也是抛出异常退出

会出让线程的执行权  

如果想退出的时候抛出来异常可以使用finally

    /**
     * 协程取消的副作用
     */
    @Test
    fun `test release resources`() = runBlocking<Unit> 
        val job = launch 
            try 
                repeat(1000)  i ->
                    println("job:I'm sleeping $i...")
                    delay(500L)
                
             finally 
                println("job : I'm running finally")
            
        

        delay(1300)
        println("main:I'm tired of waiting")
        job.cancelAndJoin()
        println("main:Now i can quit.")
    

try finlly 虽然时尚。但是kotlin有更好的标准函数 use

可以用来处理被实现了Closeable的对象 

程序结束会自动调用close方法。适合文件对象。

    @Test
    fun `test use function`() = runBlocking<Unit> 
        val filePatg =
            "H:\\\\develop\\\\project\\\\android\\\\learn\\\\coroutine\\\\app\\\\src\\\\test\\\\java\\\\com\\\\example\\\\coroutine\\\\CoroutineTest02.kt"
        println("plan1:")
        val br = BufferedReader(FileReader(filePatg))
        with(br) 
            try 
                var line: String?
                while (true) 
                    line = readLine() ?: break
                    println(line)
                
             finally 
                close()
            
        
        //还可以使用use
        println("plan2:")
        val br2 = BufferedReader(FileReader(filePatg))
        br2.use 
            var line: String?
            while (true) 
                line = it.readLine() ?: break
                println(line)
            
        


    

以上是关于Android 协程 cpu密集型任务的取消的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin 协程协程取消 ② ( CPU 密集型协程任务取消 | 使用 isActive 判定协程状态 | 使用 ensureActive 函数取消协程 | 使用 yield 函数取消协程 )

GIL线程全局锁 协程

进程线程和协程的理解-自己随笔

重述协程

python 复习—并发编程系统并发线程和进程协程GIL锁CPU/IO密集型计算

同步锁