mirror of
https://github.com/tursom/TursomServer.git
synced 2025-03-22 23:50:06 +08:00
add CurrentThreadCoroutineScope
This commit is contained in:
parent
78c06598e1
commit
f4ec9ca3c8
@ -1,31 +1,43 @@
|
|||||||
package cn.tursom.utils.coroutine
|
package cn.tursom.utils.coroutine
|
||||||
|
|
||||||
|
import cn.tursom.core.SimpThreadLocal
|
||||||
import cn.tursom.core.cast
|
import cn.tursom.core.cast
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.CoroutineStart
|
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
import kotlin.coroutines.coroutineContext
|
import kotlin.coroutines.coroutineContext
|
||||||
|
|
||||||
object CurrentThreadCoroutineScope {
|
object CurrentThreadCoroutineScope {
|
||||||
private val currentThreadCoroutineScopeThreadLocal = ThreadLocal<CoroutineScope>()
|
private val eventLoopThreadLocal: SimpThreadLocal<CoroutineDispatcher> = SimpThreadLocal {
|
||||||
|
newBlockingEventLoop()
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun getCoroutineScope(): CoroutineScope {
|
private suspend fun getCoroutineScope(): CoroutineScope {
|
||||||
return currentThreadCoroutineScopeThreadLocal.get() ?: kotlin.run {
|
val eventLoop = eventLoopThreadLocal.get()
|
||||||
val eventLoop = newBlockingEventLoop()
|
val coroutineScopeContext = CoroutineScopeContext()
|
||||||
val coroutineScope = newBlockingCoroutine(coroutineContext, Thread.currentThread(), eventLoop)
|
val newBlockingCoroutine = newBlockingCoroutine(
|
||||||
currentThreadCoroutineScopeThreadLocal.set(coroutineScope)
|
coroutineContext + coroutineScopeContext + Dispatchers.Unconfined,
|
||||||
coroutineScope
|
Thread.currentThread(),
|
||||||
}
|
eventLoop
|
||||||
|
)
|
||||||
|
coroutineScopeContext.coroutineScope = newBlockingCoroutine
|
||||||
|
return newBlockingCoroutine
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun launch(
|
suspend fun launch(
|
||||||
start: CoroutineStart = CoroutineStart.DEFAULT,
|
start: CoroutineStart = CoroutineStart.DEFAULT,
|
||||||
block: suspend CoroutineScope.() -> Unit
|
block: suspend CoroutineScope.() -> Unit
|
||||||
) {
|
): Job {
|
||||||
getCoroutineScope().start(start, block = block)
|
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 BlockingEventLoop = Class.forName("kotlinx.coroutines.BlockingEventLoop")
|
||||||
private val BlockingEventLoopConstructor = BlockingEventLoop
|
private val BlockingEventLoopConstructor = BlockingEventLoop
|
||||||
.getConstructor(Thread::class.java)
|
.getConstructor(Thread::class.java)
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package cn.tursom.utils.coroutine
|
package cn.tursom.utils.coroutine
|
||||||
|
|
||||||
import cn.tursom.core.cast
|
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
import kotlin.coroutines.coroutineContext
|
import kotlin.coroutines.coroutineContext
|
||||||
|
|
||||||
val testCoroutineLocal = CoroutineLocal<Int>()
|
val testCoroutineLocal = CoroutineLocal<Int>()
|
||||||
@ -17,37 +15,29 @@ suspend fun test() {
|
|||||||
println(Thread.currentThread().name)
|
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() {
|
suspend fun main() {
|
||||||
test()
|
|
||||||
CurrentThreadCoroutineScope.launch {
|
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)
|
delay(1000)
|
||||||
//runBlockingWithEnhanceContext {
|
//runBlockingWithEnhanceContext {
|
||||||
// println(coroutineContext)
|
// println(coroutineContext)
|
||||||
|
Loading…
Reference in New Issue
Block a user