mirror of
https://github.com/tursom/TursomServer.git
synced 2025-03-14 03:40:06 +08:00
add CurrentThreadCoroutineScope
This commit is contained in:
parent
78c06598e1
commit
f4ec9ca3c8
@ -1,31 +1,43 @@
|
||||
package cn.tursom.utils.coroutine
|
||||
|
||||
import cn.tursom.core.SimpThreadLocal
|
||||
import cn.tursom.core.cast
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.CoroutineStart
|
||||
import kotlinx.coroutines.*
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.coroutineContext
|
||||
|
||||
object CurrentThreadCoroutineScope {
|
||||
private val currentThreadCoroutineScopeThreadLocal = ThreadLocal<CoroutineScope>()
|
||||
private val eventLoopThreadLocal: SimpThreadLocal<CoroutineDispatcher> = SimpThreadLocal {
|
||||
newBlockingEventLoop()
|
||||
}
|
||||
|
||||
private suspend fun getCoroutineScope(): CoroutineScope {
|
||||
return currentThreadCoroutineScopeThreadLocal.get() ?: kotlin.run {
|
||||
val eventLoop = newBlockingEventLoop()
|
||||
val coroutineScope = newBlockingCoroutine(coroutineContext, Thread.currentThread(), eventLoop)
|
||||
currentThreadCoroutineScopeThreadLocal.set(coroutineScope)
|
||||
coroutineScope
|
||||
}
|
||||
val eventLoop = eventLoopThreadLocal.get()
|
||||
val coroutineScopeContext = CoroutineScopeContext()
|
||||
val newBlockingCoroutine = newBlockingCoroutine(
|
||||
coroutineContext + coroutineScopeContext + Dispatchers.Unconfined,
|
||||
Thread.currentThread(),
|
||||
eventLoop
|
||||
)
|
||||
coroutineScopeContext.coroutineScope = newBlockingCoroutine
|
||||
return newBlockingCoroutine
|
||||
}
|
||||
|
||||
suspend fun launch(
|
||||
start: CoroutineStart = CoroutineStart.DEFAULT,
|
||||
block: suspend CoroutineScope.() -> Unit
|
||||
) {
|
||||
getCoroutineScope().start(start, block = block)
|
||||
): Job {
|
||||
val coroutineScope = getCoroutineScope()
|
||||
//coroutineScope.launch(start = start, block = block)
|
||||
coroutineScope.start(start, block = block)
|
||||
return coroutineScope as Job
|
||||
}
|
||||
|
||||
private val EventLoop = Class.forName("kotlinx.coroutines.EventLoop")
|
||||
private val EventLoopShouldBeProcessedFromContext = EventLoop.methods
|
||||
.first { it.name == "shouldBeProcessedFromContext" }
|
||||
.apply { isAccessible = true }
|
||||
|
||||
private val BlockingEventLoop = Class.forName("kotlinx.coroutines.BlockingEventLoop")
|
||||
private val BlockingEventLoopConstructor = BlockingEventLoop
|
||||
.getConstructor(Thread::class.java)
|
||||
|
@ -1,8 +1,6 @@
|
||||
package cn.tursom.utils.coroutine
|
||||
|
||||
import cn.tursom.core.cast
|
||||
import kotlinx.coroutines.*
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.coroutineContext
|
||||
|
||||
val testCoroutineLocal = CoroutineLocal<Int>()
|
||||
@ -17,37 +15,29 @@ suspend fun test() {
|
||||
println(Thread.currentThread().name)
|
||||
}
|
||||
|
||||
val EventLoop = Class.forName("kotlinx.coroutines.EventLoop")
|
||||
val AbstractCoroutine = Class.forName("kotlinx.coroutines.AbstractCoroutine")
|
||||
|
||||
val BlockingEventLoop = Class.forName("kotlinx.coroutines.BlockingEventLoop")
|
||||
val BlockingEventLoopConstructor = BlockingEventLoop.getConstructor(Thread::class.java).apply { isAccessible = true }
|
||||
fun newBlockingEventLoop(thread: Thread = Thread.currentThread()): CoroutineDispatcher {
|
||||
return BlockingEventLoopConstructor.newInstance(thread) as CoroutineDispatcher
|
||||
}
|
||||
|
||||
val BlockingCoroutine = Class.forName("kotlinx.coroutines.BlockingCoroutine")
|
||||
val BlockingCoroutineConstructor = BlockingCoroutine.constructors[0].apply { isAccessible = true }
|
||||
val BlockingCoroutineStart = BlockingCoroutine.methods.first { it.name == "start" && it.parameters.size == 3 }.apply { isAccessible = true }
|
||||
val BlockingCoroutineJoinBlocking = BlockingCoroutine.methods.first { it.name == "joinBlocking" }.apply { isAccessible = true }
|
||||
|
||||
fun newBlockingCoroutine(coroutineContext: CoroutineContext, thread: Thread = Thread.currentThread(), eventLoop: CoroutineDispatcher): CoroutineScope {
|
||||
return BlockingCoroutineConstructor.newInstance(coroutineContext, thread, eventLoop).cast()
|
||||
}
|
||||
|
||||
fun CoroutineScope.start(start: CoroutineStart = CoroutineStart.DEFAULT, receiver: CoroutineScope = this, block: suspend CoroutineScope.() -> Any?) {
|
||||
return BlockingCoroutineStart.invoke(this, start, receiver, block).cast()
|
||||
}
|
||||
|
||||
fun CoroutineScope.joinBlocking() {
|
||||
BlockingCoroutineJoinBlocking.invoke(this)
|
||||
}
|
||||
|
||||
suspend fun main() {
|
||||
test()
|
||||
CurrentThreadCoroutineScope.launch {
|
||||
test()
|
||||
println("Unconfined : I'm working in thread ${Thread.currentThread().name}")
|
||||
delay(50)
|
||||
println("Unconfined : After delay in thread ${Thread.currentThread().name}")
|
||||
delay(50)
|
||||
println("Unconfined : After delay in thread ${Thread.currentThread().name}")
|
||||
}
|
||||
GlobalScope.launch(Dispatchers.Unconfined) { // 非受限的——将和主线程一起工作
|
||||
println("Unconfined : I'm working in thread ${Thread.currentThread().name}")
|
||||
delay(50)
|
||||
println("Unconfined : After delay in thread ${Thread.currentThread().name}")
|
||||
delay(50)
|
||||
println("Unconfined : After delay in thread ${Thread.currentThread().name}")
|
||||
}
|
||||
GlobalScope.launch { // 父协程的上下文,主 runBlocking 协程
|
||||
println("main runBlocking: I'm working in thread ${Thread.currentThread().name}")
|
||||
delay(100)
|
||||
println("main runBlocking: After delay in thread ${Thread.currentThread().name}")
|
||||
delay(100)
|
||||
println("main runBlocking: After delay in thread ${Thread.currentThread().name}")
|
||||
}
|
||||
println("end")
|
||||
delay(1000)
|
||||
//runBlockingWithEnhanceContext {
|
||||
// println(coroutineContext)
|
||||
|
Loading…
Reference in New Issue
Block a user