import kotlinx.coroutines.*
import org.junit.jupiter.api.Test
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import kotlin.coroutines.CoroutineContext
class TestCoroutine {
/**
* 同步阻塞执行
*/
@Test
fun testRunBlockLaunch() {
println("同步协议启动start")
runBlocking {
Thread.sleep(2)
println("runBlocking 1")
runBlocking {
Thread.sleep(2)
println("sub runBlocking ")
}
println("runBlocking 2")
}
println("end")
}
/**
* 使用应用范围(GlobalScope)的协程执行,非同步
* 不能使线程保活,类守护线程,线程退出协程可能还末执行完成
*/
@Test
fun testGlobalScopeLaunch() {
println("start")
GlobalScope.launch {
Thread.sleep(2000)
println("GlobalScope launch 1")
GlobalScope.launch {
Thread.sleep(3000)
println("sub launch ")
}
println("GlobalScope launch 2")
}
println("end")
}
/**
* launch 与 async 都是异步执行且都需要在协程环境中
* 区别,async是带返回值的
*/
@Test
fun testGlobalScopeAsyncLaunch() {
println("start")
GlobalScope.launch {
Thread.sleep(1000)
println("GlobalScope launch 1")
val job = launch {
Thread.sleep(1000)
println("sub launch ")
}
println("job.isActive=${job.isActive}")
//job.cancel()
val deffer = async {
println("sub async ")
"aa"
}
println("GlobalScope launch 2")
val defferResult = deffer.await()
println("defferResult= $defferResult")
}
println("end")
Thread.sleep(5000)
}
@Test
fun testGlobalScopeExceptionLaunch() {
println("start")
MyCoroutineScope().launch {
//A 与 B同一个launch的子类,A异常会中断,B将无法执行
async {
println("A sub async ")
//Thread.sleep(1000)
throw IllegalAccessException()
}
launch {
println("B1 sub launch ")
throw IllegalAccessException()
}
launch {
println("B2 sub launch ")
throw IllegalAccessException()
}
}
//A 异常并不影响C执行
MyCoroutineScope().launch {
launch {
Thread.sleep(1000)
println("C launch ")
throw IllegalAccessException()
}
}
println("end")
Thread.sleep(6000)
}
@Test
fun testGlobalScopeContextLaunch() {
println("start")
GlobalScope.launch {
launch(CoroutineName("testA")) {
println("currentThread = ${Thread.currentThread()}")
throw IllegalAccessException()
}
launch(CoroutineName("testB")) {
println("currentThread = ${Thread.currentThread()}")
throw IllegalAccessException()
}
println("GlobalScope.launch thread: ${Thread.currentThread()}")
}
println("end")
Thread.sleep(3000)
}
@Test
fun testGlobalScopeWithLaunch() {
println("start")
MyCoroutineScope().launch {
println("GlobalScope.launch thread: ${Thread.currentThread()} ${this.coroutineContext.job.key}")
launch {
withContext(Dispatchers.Default) {
println("with Dispatchers.Default = ${Thread.currentThread()}")
}
}
withContext(Dispatchers.Unconfined) {
println("with Dispatchers.Main = ${Thread.currentThread()}")
}
getLoadData()
}
println("end")
Thread.sleep(3000)
}
suspend fun getLoadData() = withContext(Dispatchers.IO) {
println("LoadData")
Thread.sleep(1000)
println("CoroutineScope with Dispatchers.IO = ${Thread.currentThread()}" + this.coroutineContext.job)
}
@Test
fun testGlobalLaunch() {
val myCoroutine = MyCoroutineScope()
myCoroutine.launch {
println("a线程:" + Thread.currentThread())
withContext(Dispatchers.Default) {
println("b:" + Thread.currentThread())//Thread[DefaultDispatcher-worker-1 @coroutine#1,5,main]
}
}
Thread.sleep(2000)
}
val exceptionHandler = CoroutineExceptionHandler { context, ex ->
println("异常信息:" + ex.printStackTrace())
}
val excutor = Executors.newFixedThreadPool(5, NamedThreadFactory("myExecutors"))
val myDispatcher = MyDispatcher(excutor)
val myCoroutineContext =
SupervisorJob() + myDispatcher + CoroutineName("MyCoroutineName") + exceptionHandler
//val myCoroutineScope = MyContextScope(context)
val myCoroutineScope = CoroutineScope(myCoroutineContext)
@Test
fun testCustomerLaunchJob() {
myCoroutineScope.launch {
println("线程:" + Thread.currentThread())
val job = async {
println("sub线程:" + Thread.currentThread())
}
job.await()
println("-------")
}
println("end")
//excutor.awaitTermination(5, TimeUnit.SECONDS)
Thread.sleep(6000)
}
}
/**
* 自定义dispatcher指定执行的线程池
*/
class MyDispatcher(val executors: ExecutorService) : CoroutineDispatcher() {
override fun dispatch(context: CoroutineContext, block: Runnable) {
executors.execute(block)
}
}
class MyCoroutineScope : CoroutineScope {
val exceptionHandler = CoroutineExceptionHandler { context, ex ->
println("异常信息:" + ex.printStackTrace())
}
override val coroutineContext: CoroutineContext
get() = Job() + Dispatchers.Default + CoroutineName("mytest") + exceptionHandler
}