基本使用
package outtime
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeout
/**
* 超时:动追踪一个相关 Job 的引用并启动了一个单独的协程
* 在延迟后取消追踪,使用 withTimeout 函数来做这件事
* 1、withTimeout 会抛出异常 TimeoutCancellationException <-extend--- CancellationException
* 2、
*/
fun main() = runBlocking {
withTimeout(1300L) {
repeat(1000){
i ->
println("i==$i")
delay(500L)
}
}
// output:
// i==0
// i==1
// i==2
// Exception ===> in thread "main" kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 1300 ms
}
超时取消 不报错TimeoutCancellationException
package outtime
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeoutOrNull
/**
* 使用withTimeoutOrNull 通过返回 null 来进行超时操作,从而替代抛出一个异常
*/
fun main() = runBlocking {
val result = withTimeoutOrNull(1300L) {
repeat(1000){
i ->
println("i==$i")
delay(500L)
}
"Done"
}
println("Result is $result")
// output:
// i==0
// i==1
// i==2
// Result is null
}
超时释放资源,线程安全,输出不一定是0
package outtime
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeout
var ab = 0
/**
* absl withTimeout内初始化 输出的并不一定是0
* 协程递增和递减获得的计数器是完全安全的,因为它总是发生在同一个主线程上
*/
class abs{
init {
ab ++
}
fun close(){
ab --
}
}
/**
* withTimeout中的超时事件与在其块中运行的代码是异步的,
* 并且可能随时发生,甚至在从timeout块内部返回之前。
* 如果在块内打开或获取一些需要在块外关闭或释放的资源
*/
fun main() {
runBlocking {
repeat(100_000) {
launch {
val resource = withTimeout(60) { // Timeout of 60 ms
delay(50) // Delay for 50 ms
abs() // Acquire a resource and return it from withTimeout block
}
resource.close()
}
}
}
// Outside of runBlocking all coroutines have completed
println(ab) // Print the number of resources still acqui
// output:
// 0
// 1021
}
解决释放资源不是0的问题–存储变量对象
```kotlin
package outtime
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeout
var abl = 0
/**
* absl withTimeout外初始化
* 在变量中存储对资源的引用
* 输出的是0
*/
class absl {
init {
abl++
}
fun close() {
abl--
}
}
/**
* withTimeout中的超时事件与在其块中运行的代码是异步的,
* 并且可能随时发生,甚至在从timeout块内部返回之前。
* 如果在块内打开或获取一些需要在块外关闭或释放的资源
*/
fun main() {
runBlocking {
repeat(100_000) {
launch {
var resource: absl? = null
withTimeout(60) { // Timeout of 60 ms
delay(50) // Delay for 50 ms
// Acquire a resource and return it from withTimeout block
resource = absl()
}
resource?.close()
}
}
}
// Outside of runBlocking all coroutines have completed
println(ab) // Print the number of resources still acqui
// output:
// 0
}