对于了解协程(微线程,Coroutine),其实很早就有协程的概念,在Lua,Python,go语言中较为常见Android在kotlin拓展库kotlinx.coroutines去提供使用。
首先讲起进程和线程
进程拥有切换和打开的进程表,文件资源、数据资源、独立的内存空间。
线程从属于进程,是程序的实际执行者,一个进程至少包含一个主线程,也可以有更多的子线程,线程拥有自己的栈空间。
线程具有五种状态:初始化、可运行、运行中、阻塞、销毁。
协程
协程不同与进程或线程是比线程更加轻量级的存在,一个进程可以拥有多个线程,一个线程可以拥有多个协程,协程有自己控制的上下文。
进程和线程都是由是操作系统的调度切换策略去执行,而协程的切换时机则是用户自己的程序所决定的。
协程是不需要多线程的锁机制,减少资源消耗。
协程提升CPU利用率,减少线程切换,提升程序运行效率。
总结协程:可控制 轻量级 语法糖。
常用API
runBlocking
//启动执行协程任务
launch
//执行协程任务
//启动参数
- 当前协程上下文,可声明切换调度器模式
- context: CoroutineContext = EmptyCoroutineContext
- 可自定义启动方式
- start: CoroutineStart = CoroutineStart.DEFAULT,
- 闭包形式的协程函数
- block: suspend CoroutineScope.() -> T
asyns/await
//执行协程任务/得到返回结果
协程工厂函数
val scope = MainScope()
scope.async(Dispatchers.Default) {}
scope.launch {}
scope.cancel()
withContext
withContext(Dispatchers.Default){}
Dispatchers提供四种不同属性提供不同的线程支持和操作Default Main Unconfined IO
反编译源码分析
runBlocking
fun main() = runBlocking {
listCoroutineScope()
}
//反编译源码
public final List<Font> main() {
return (List) BuildersKt__BuildersKt.runBlocking$default((CoroutineContext) null, new FontService$main$1((Continuation) null), 1, (Object) null);
}
// FontService$main$1
@Metadata(bv = {1, 0, 3}, d1 = {"\u0000\u0012\n\u0000\n\u0002\u0010!\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\u0010\u0000\u001a\b\u0012\u0004\u0012\u00020\u00020\u0001*\u00020\u0003HŠ@¢\u0006\u0004\b\u0004\u0010\u0005"}, d2 = {"<anonymous>", "", "Lcom/hyfontstudio/fontspro/base/Font;", "Lkotlinx/coroutines/CoroutineScope;", "invoke", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"}, k = 3, mv = {1, 1, 16})
/* compiled from: FontService.kt */
final class FontService$main$1 extends SuspendLambda implements Function2<CoroutineScope, Continuation<? super List<Font>>, Object> {
int label;
private CoroutineScope p$;
FontService$main$1(Continuation continuation) {
super(2, continuation);
}
public final Continuation<Unit> create(Object obj, Continuation<?> continuation) {
Intrinsics.checkParameterIsNotNull(continuation, "completion");
FontService$main$1 fontService$main$1 = new FontService$main$1(continuation);
CoroutineScope coroutineScope = (CoroutineScope) obj;
fontService$main$1.p$ = (CoroutineScope) obj;
return fontService$main$1;
}
public final Object invoke(Object obj, Object obj2) {
return ((FontService$main$1) create(obj, (Continuation) obj2)).invokeSuspend(Unit.INSTANCE);
}
public final Object invokeSuspend(Object $result) {
IntrinsicsKt.getCOROUTINE_SUSPENDED();
if (this.label == 0) {
ResultKt.throwOnFailure($result);
CoroutineScope coroutineScope = this.p$;
return FontService.Companion.listCoroutineScope();
}
throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
}
}
fun listCoroutineScope() =
runBlocking {
async {
print("Thread:::${Thread.currentThread().name}")
}.await()
}
//反编译源码
public final List<Font> listCoroutineScope() {
return (List) BuildersKt__BuildersKt.runBlocking$default((CoroutineContext) null, new FontService$Companion$listCoroutineScope$1((Continuation) null), 1, (Object) null);
}
//FontService$Companion$listCoroutineScope$1
@Metadata(bv = {1, 0, 3}, d1 = {"\u0000\u0012\n\u0000\n\u0002\u0010!\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\u0010\u0000\u001a\b\u0012\u0004\u0012\u00020\u00020\u0001*\u00020\u0003HŠ@¢\u0006\u0004\b\u0004\u0010\u0005"}, d2 = {"<anonymous>", "", "Lcom/hyfontstudio/fontspro/base/Font;", "Lkotlinx/coroutines/CoroutineScope;", "invoke", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"}, k = 3, mv = {1, 1, 16})
@DebugMetadata(c = "com.hyfontstudio.fontspro.ime.core.FontService$Companion$listCoroutineScope$1", f = "FontService.kt", i = {0}, l = {109}, m = "invokeSuspend", n = {"$this$runBlocking"}, s = {"L$0"})
/* compiled from: FontService.kt */
final class FontService$Companion$listCoroutineScope$1 extends SuspendLambda implements Function2<CoroutineScope, Continuation<? super List<Font>>, Object> {
Object L$0;
int label;
private CoroutineScope p$;
FontService$Companion$listCoroutineScope$1(Continuation continuation) {
super(2, continuation);
}
public final Continuation<Unit> create(Object obj, Continuation<?> continuation) {
Intrinsics.checkParameterIsNotNull(continuation, "completion");
FontService$Companion$listCoroutineScope$1 fontService$Companion$listCoroutineScope$1 = new FontService$Companion$listCoroutineScope$1(continuation);
CoroutineScope coroutineScope = (CoroutineScope) obj;
fontService$Companion$listCoroutineScope$1.p$ = (CoroutineScope) obj;
return fontService$Companion$listCoroutineScope$1;
}
public final Object invoke(Object obj, Object obj2) {
return ((FontService$Companion$listCoroutineScope$1) create(obj, (Continuation) obj2)).invokeSuspend(Unit.INSTANCE);
}
public final Object invokeSuspend(Object $result) {
Object coroutine_suspended = IntrinsicsKt.getCOROUTINE_SUSPENDED();
int i = this.label;
if (i == 0) {
ResultKt.throwOnFailure($result);
CoroutineScope $this$runBlocking = this.p$;
Deferred async$default = BuildersKt__Builders_commonKt.async$default($this$runBlocking, (CoroutineContext) null, (CoroutineStart) null, new AnonymousClass1((Continuation) null), 3, (Object) null);
this.L$0 = $this$runBlocking;
this.label = 1;
Object await = async$default.await(this);
if (await == coroutine_suspended) {
return coroutine_suspended;
}
CoroutineScope coroutineScope = $this$runBlocking;
return await;
} else if (i == 1) {
CoroutineScope $this$runBlocking2 = (CoroutineScope) this.L$0;
ResultKt.throwOnFailure($result);
return $result;
} else {
throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
}
}
@Metadata(bv = {1, 0, 3}, d1 = {"\u0000\u0012\n\u0000\n\u0002\u0010!\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\u0010\u0000\u001a\b\u0012\u0004\u0012\u00020\u00020\u0001*\u00020\u0003HŠ@¢\u0006\u0004\b\u0004\u0010\u0005"}, d2 = {"<anonymous>", "", "Lcom/hyfontstudio/fontspro/base/Font;", "Lkotlinx/coroutines/CoroutineScope;", "invoke", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"}, k = 3, mv = {1, 1, 16})
@DebugMetadata(c = "com.hyfontstudio.fontspro.ime.core.FontService$Companion$listCoroutineScope$1$1", f = "FontService.kt", i = {}, l = {}, m = "invokeSuspend", n = {}, s = {})
/* renamed from: com.hyfontstudio.fontspro.ime.core.FontService$Companion$listCoroutineScope$1$1 reason: invalid class name */
/* compiled from: FontService.kt */
static final class AnonymousClass1 extends SuspendLambda implements Function2<CoroutineScope, Continuation<? super List<Font>>, Object> {
int label;
private CoroutineScope p$;
public final Continuation<Unit> create(Object obj, Continuation<?> continuation) {
Intrinsics.checkParameterIsNotNull(continuation, "completion");
AnonymousClass1 r0 = new AnonymousClass1(continuation);
CoroutineScope coroutineScope = (CoroutineScope) obj;
r0.p$ = (CoroutineScope) obj;
return r0;
}
public final Object invoke(Object obj, Object obj2) {
return ((AnonymousClass1) create(obj, (Continuation) obj2)).invokeSuspend(Unit.INSTANCE);
}
public final Object invokeSuspend(Object $result) {
IntrinsicsKt.getCOROUTINE_SUSPENDED();
if (this.label == 0) {
ResultKt.throwOnFailure($result);
CoroutineScope coroutineScope = this.p$;
StringBuilder sb = new StringBuilder();
sb.append("Thread:::");
Thread currentThread = Thread.currentThread();
Intrinsics.checkExpressionValueIsNotNull(currentThread, "Thread.currentThread()");
sb.append(currentThread.getName());
System.out.print(sb.toString());
return FontService.Companion.getResourcesJsonList();
}
throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");
}
}
}
源码留到下一篇分析…