📅  最后修改于: 2023-12-03 15:32:31.187000             🧑  作者: Mango
Kotlin 是一门运行在 JVM 上的编程语言,因此它也继承了 Java 的线程模型。
Kotlin 为线程编程提供了方便的 API,并且通过协程的支持,也使得异步编程更加简单。
在 Kotlin 中,可以通过 thread
函数来创建新线程。
import kotlin.concurrent.thread
fun main() {
thread {
// 开始执行的代码
}
}
thread
函数接受一个 Lambda 表达式作为线程的执行体。
该函数还可以接受一个名为 name
的可选参数,指定线程的名称。
另外,thread
函数还有一个重载版本,可以接受一个 Runnable
对象作为线程的执行体。
import kotlin.concurrent.thread
fun main() {
thread(Runnable {
// 开始执行的代码
})
}
由于多个线程之间共享资源,因此可能会出现线程安全的问题。
Kotlin 提供了一些工具来帮助我们避免这些问题。
synchronized
关键字可以将一段代码块标记为临界区(critical section),同一时间只有一个线程可以进入该块执行。
class Counter {
private var count = 0
// 使用 synchronized 关键字保证 count 的线程安全
@Synchronized
fun inc() {
count++
}
fun get() = count
}
fun main() {
val counter = Counter()
(1..1000).forEach {
thread {
counter.inc()
}
}
Thread.sleep(1000)
println(counter.get()) // 1000
}
Atomic
类提供了原子操作,可以保证对于单个操作的执行不会被其他线程打断。
import java.util.concurrent.atomic.AtomicInteger
class Counter {
private var count = AtomicInteger(0)
fun inc() {
count.getAndIncrement()
}
fun get() = count.get()
}
fun main() {
val counter = Counter()
(1..1000).forEach {
thread {
counter.inc()
}
}
Thread.sleep(1000)
println(counter.get()) // 1000
}
volatile
关键字可以保证线程之间对变量的修改可见,并且禁止 CPU 缓存这个变量的值。
@Volatile
var stop = false
fun main() {
thread {
while (!stop) {
// 执行一些操作
}
}
Thread.sleep(1000)
stop = true
}
协程是执行异步代码的一种轻量级解决方案。
Kotlin 通过 suspend
关键字和协程构建器来支持协程。
在函数声明中使用 suspend
关键字标记该函数为挂起函数。
挂起函数可以在一定程度上取代回调函数,简化异步编程。
suspend fun doSomethingAsync() {
// 执行异步操作,如网络请求或数据库查询
}
协程构建器是启动协程的工具,Kotlin 支持以下几种协程构建器:
launch
async
runBlocking
withContext
coroutineScope
其中,launch
和 async
最常用。
launch
创建一个新协程,并立即返回。
import kotlinx.coroutines.*
fun main() {
GlobalScope.launch {
doSomethingAsync()
}
}
async
创建一个新协程,并返回一个 Deferred
对象。
Deferred
对象包含一个值(或异常),可以通过 await
方法获取。
import kotlinx.coroutines.*
fun main() = runBlocking {
val result = GlobalScope.async {
doSomethingAsync()
}.await()
println(result)
}
在 runBlocking
中启动协程可以等待所有协程执行完毕后退出程序。
withContext
函数可以在协程中切换线程,并且等待执行完毕后返回结果。
import kotlinx.coroutines.*
suspend fun loadUserData(userId: Int): String = withContext(Dispatchers.IO) {
// 执行耗时操作,如网络请求或数据库查询
val result = // ...
result
}
fun main() = runBlocking {
val result = loadUserData(1)
println(result)
}
coroutineScope
函数可以启动一个新协程作用域,并且等待其中的协程执行完毕后返回结果。
import kotlinx.coroutines.*
suspend fun doSomething(): String {
delay(1000)
return "Hello, world!"
}
suspend fun doSomethingElse(): String {
delay(1000)
return "Hi there!"
}
suspend fun doBoth(): String = coroutineScope {
val result1 = async { doSomething() }
val result2 = async { doSomethingElse() }
result1.await() + " " + result2.await()
}
fun main() = runBlocking {
val result = doBoth()
println(result)
}
Kotlin 提供了方便的线程编程 API 和支持协程的语言特性,使得异步编程更加简单和优雅。