// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.4.32"
// 协程核心库
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.3"
// 协程Android支持库
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.3"
fun main(){
GlobalScope.launch{
Log.d("launch", "启动一个协程")
}
}
这个函数可以创建一个协程作用域,传递给launch函数的代码块,在协程中进行运行。
运行上面的函数日志是不能打印出的,因为,GlobalScope.launch函数每次创建的都是一个顶层协程,这个协程在应用程序结束时也会一起结束,代码块未来的及执行程序就i结束了。
fun main(){GlobalScope.launch{
Log.d("launch", "启动一个协程")
delay(1500)
Log.d("launch", "协程结束")
}
Thread.sleep(1000)
}
我们尝试去阻塞主线程,让主线程延迟时间,但是当协程内的代码在阻塞时间内无法执行完成时,日志依旧无法被打印出。delay()函数可以让当前协程延迟指定时间在执行,和Thead.sleep()不同的是,delay函数是一个非阻塞式挂起函数,只会挂起当前线程,并不会影响其他协程的运行而Thead.sleep()会阻塞当前线程,运行在该线程下的所有协程都会被阻塞,delay函数只能在协程的作用域或其他挂起函数中调用。
runBlocking函数,函数会创建一个协程的作用域,他会在协程作用域内的所有子协程没有执行完成前一直阻塞当前线程。
fun(){
runBlocking(){
println("执行协程")
delay(1500)
println("完成")
}
}
多个协程的使用:
fun(){
runBlocking(){
launch(){
println("执行协程")
delay(1500)
println("完成")
}
launch(){
println("执行协程")
delay(1500)
println("完成")
}
}
}
这里使用了launch函数,与刚才使用的GlobalScope.launch函数不同,这个函数必须在协程的作用域内才可以调用,他会在当前协程的作用域下创建子协程,子协程的特点是:如果外层作用域的协程结束了,该作用域下的所有子协程也会一并结束,GlobalScope.launch函数则一直创建的函数一直是顶层协程。
这俩个子协程的确是并发的,但是他们实际却在一个线程中执行,有编程语言来决定谁挂起,谁运行。调度的过程不需要操作系统参与,所以并发效率会很高。
fun main() {
val start = System.currentTimeMillis()
runBlocking{
repeat(100000){
launch{
println(".")
}
}
}
val end = System.currentTimeMillis()
println(end - start)
}
Suspend:将任意函数声明为挂起函数,挂起函数之间是可以进行互相调用的。
suspend fun klo(){
println(".")
delay(1000)
}
suspend只能声明挂起函数,不能提供作用域,不能进行子协程的开启。借助coroutineScope函数,这个挂起函数可以在其他挂起函数中进行调用,他会继承外部协程的作用域并创建一个子协程,可以给挂起函数提供作用域。
suspend fun klo() =
coroutineScope{
launch{
println(".")
delay(1000)
}
}
和runblocking相似,这个函数可以保证在其作用域内的所有代码和子协程执行完成前,外部的协程会一直被挂起。
coroutineScope函数只能阻塞当前协程,不会阻塞任何其他的协程和线程。而runblocking函数会挂起外部线程,如果你在主线程调用它可能会导致界面卡死。
取消协程:
launch函数,他们执行会返回一个job对象,调用job的cancel方法就可以将协程取消。
fun main(){
val job = GlobalScope.launch{
Log.d("launch", "启动一个协程")
}
job.cancel()
}
ansync函数:
ansync函数返回的是一个Deferred对象,通过调用Deferred函数的await()方法获取返回值。
fun main(){
runBlocking{
val result = ansync{
5 + 5
}.await()
prontln(result)
}
}
当调用ansync里面的await函数时,如果协程内的代码块未执行完,那么await函数会将当前协程阻塞住,知道ansync的结果被获取到。
fun main(){
runBlocking{
val result1 = ansync{
delay(1000)
5 + 5
}.await()
prontln(result)
}
val result2 = ansync{
delay(1500)
4 + 6
}.await()
println("result is $result1 + $result2")
}