Kotlin协程(Coroutine)的使用以及源码分析

对于了解协程(微线程,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");
    }
}
}

源码留到下一篇分析…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值