Logo
Section 1 / 7

简介:协程的内部原理

了解协程和函数在底层的实现原理。

导入

简介:协程的内部原理

了解协程和函数在底层的实现原理。

延续传递风格(Continuation-passing style)

1suspend fun getUser(): User? 2suspend fun setUser(user: User) 3suspend fun checkAvailability(flight: Flight): Boolean 4 5// 底层实现为 6fun getUser(continuation: Continuation<*>): Any? 7fun setUser(user: User, continuation: Continuation<*>): Any 8fun checkAvailability( 9 flight: Flight, 10 continuation: Continuation<*> 11): Any

一个简单示例

1suspend fun myFunction() { 2 println("Before") 3 delay(1000) // 挂起操作 4 println("After") 5}

底层函数签名

1fun myFunction(continuation: Continuation<*>): Any

将延续封装在独立函数中

1val continuation = MyFunctionContinuation(continuation)
1val continuation = 2 if (continuation is MyFunctionContinuation) continuation 3 else MyFunctionContinuation(continuation)
1val continuation = continuation as? MyFunctionContinuation 2 ?: MyFunctionContinuation(continuation)
1suspend fun myFunction() { 2 println("Before") 3 delay(1000) // 挂起操作 4 println("After") 5}
1// myFunction 底层简化实现 2fun myFunction(continuation: Continuation<Unit>): Any { 3 val continuation = continuation as? MyFunctionContinuation 4 ?: MyFunctionContinuation(continuation) 5 6 if (continuation.label == 0) { 7 println("Before") 8 continuation.label = 1 9 if (delay(1000, continuation) == COROUTINE_SUSPENDED) { 10 return COROUTINE_SUSPENDED 11 } 12 } 13 if (continuation.label == 1) { 14 println("After") 15 return Unit 16 } 17 error("Impossible") 18}
1cont = object : ContinuationImpl(continuation) { 2 var result: Any? = null 3 var label = 0 4 5 override fun invokeSuspend(`$result$: Any?): Any? { 6 this.result = $result`; 7 return myFunction(this); 8 } 9}
1// ================f_104_under_the_hood/s_1/MyFunctionContinuation.class ================= 2// class version 52.0 (52) 3// access flags 0x31 4// signature Ljava/lang/Object;Lkotlin/coroutines/Continuation<Lkotlin/Unit;>; 5// declaration: f_104_under_the_hood/s_1/MyFunctionContinuation implements kotlin.coroutines.Continuation<kotlin.Unit> 6public final class f_104_under_the_hood/s_1/MyFunctionContinuation implements kotlin/coroutines/Continuation { 7 8 9 // access flags 0x1 10 public getContext()Lkotlin/coroutines/CoroutineContext; 11 @Lorg/jetbrains/annotations/NotNull;() // invisible 12 L0 13 LINENUMBER 33 L0 14 ALOAD 0 15 GETFIELD f_104_under_the_hood/s_1/MyFunctionContinuation.completion : Lkotlin/coroutines/Continuation; 16 INVOKEINTERFACE kotlin/coroutines/Continuation.getContext ()Lkotlin/coroutines/CoroutineContext; (itf) 17 ARETURN 18 L1 19 LOCALVARIABLE this Lf_104_under_the_hood/s_1/MyFunctionContinuation; L0 L1 0 20 MAXSTACK = 1 21 MAXLOCALS = 1 22 23 // access flags 0x2 24 private I label 25 26 // access flags 0x11 27 public final getLabel()I 28 L0 29 LINENUMBER 35 L0 30 ALOAD 0 31 GETFIELD f_104_under_the_hood/s_1/MyFunctionContinuation.label : I 32 IRETURN 33 L1 34 LOCALVARIABLE this Lf_104_under_the_hood/s_1/MyFunctionContinuation; L0 L1 0 35 MAXSTACK = 1 36 MAXLOCALS = 1 37 38 // access flags 0x11 39 public final setLabel(I)V 40 // annotable parameter count: 1 (visible) 41 // annotable parameter count: 1 (invisible) 42 L0 43 LINENUMBER 35 L0 44 ALOAD 0 45 ILOAD 1 46 PUTFIELD f_104_under_the_hood/s_1/MyFunctionContinuation.label : I 47 RETURN 48 L1 49 LOCALVARIABLE this Lf_104_under_the_hood/s_1/MyFunctionContinuation; L0 L1 0 50 LOCALVARIABLE <set-?> I L0 L1 1 51 MAXSTACK = 2 52 MAXLOCALS = 2 53 54 // access flags 0x2 55 // signature Lkotlin/Result<+Ljava/lang/Object;>; 56 // declaration: result extends kotlin.Result<? extends java.lang.Object> 57 private Lkotlin/Result; result 58 @Lorg/jetbrains/annotations/Nullable;() // invisible 59 60 // access flags 0x11 61 // signature ()Lkotlin/Result<Ljava/lang/Object;>; 62 // declaration: kotlin.Result<java.lang.Object> getResult-xLWZpok() 63 public final getResult-xLWZpok()Lkotlin/Result; 64 @Lorg/jetbrains/annotations/Nullable;() // invisible 65 L0 66 LINENUMBER 36 L0 67 ALOAD 0 68 GETFIELD f_104_under_the_hood/s_1/MyFunctionContinuation.result : Lkotlin/Result; 69 ARETURN 70 L1 71 LOCALVARIABLE this Lf_104_under_the_hood/s_1/MyFunctionContinuation; L0 L1 0 72 MAXSTACK = 1 73 MAXLOCALS = 1 74 75 // access flags 0x11 76 // signature (Lkotlin/Result<+Ljava/lang/Object;>;)V 77 // declaration: void setResult(kotlin.Result<? extends java.lang.Object>) 78 public final setResult(Lkotlin/Result;)V 79 // annotable parameter count: 1 (visible) 80 // annotable parameter count: 1 (invisible) 81 @Lorg/jetbrains/annotations/Nullable;() // invisible, parameter 0 82 L0 83 LINENUMBER 36 L0 84 ALOAD 0 85 ALOAD 1 86 PUTFIELD f_104_under_the_hood/s_1/MyFunctionContinuation.result : Lkotlin/Result; 87 RETURN 88 L1 89 LOCALVARIABLE this Lf_104_under_the_hood/s_1/MyFunctionContinuation; L0 L1 0 90 LOCALVARIABLE <set-?> Lkotlin/Result; L0 L1 1 91 MAXSTACK = 2 92 MAXLOCALS = 2 93 94 // access flags 0x1 95 public resumeWith(Ljava/lang/Object;)V 96 // annotable parameter count: 1 (visible) 97 // annotable parameter count: 1 (invisible) 98 @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 99 TRYCATCHBLOCK L0 L1 L2 java/lang/Throwable 100 L3 101 LINENUMBER 39 L3 102 ALOAD 0 103 ALOAD 1 104 INVOKESTATIC kotlin/Result.box-impl (Ljava/lang/Object;)Lkotlin/Result; 105 PUTFIELD f_104_under_the_hood/s_1/MyFunctionContinuation.result : Lkotlin/Result; 106 L4 107 LINENUMBER 40 L4 108 L0 109 NOP 110 L5 111 LINENUMBER 41 L5 112 ALOAD 0 113 CHECKCAST kotlin/coroutines/Continuation 114 INVOKESTATIC f_104_under_the_hood/s_1/_1Kt.myFunction (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; 115 ASTORE 3 116 L6 117 LINENUMBER 42 L6 118 ALOAD 3 119 INVOKESTATIC f_104_under_the_hood/s_1/_1Kt.getCOROUTINE_SUSPENDED ()Ljava/lang/Object; 120 INVOKESTATIC kotlin/jvm/internal/Intrinsics.areEqual (Ljava/lang/Object;Ljava/lang/Object;)Z 121 IFEQ L7 122 RETURN 123 L7 124 LINENUMBER 43 L7 125 GETSTATIC kotlin/Result.Companion : Lkotlin/Result$Companion; 126 ASTORE 4 127 ALOAD 3 128 DUP 129 IFNONNULL L8 130 NEW java/lang/NullPointerException 131 DUP 132 LDC "null cannot be cast to non-null type kotlin.Unit" 133 INVOKESPECIAL java/lang/NullPointerException.<init> (Ljava/lang/String;)V 134 ATHROW 135 L8 136 CHECKCAST kotlin/Unit 137 ASTORE 5 138 L9 139 ALOAD 5 140 INVOKESTATIC kotlin/Result.constructor-impl (Ljava/lang/Object;)Ljava/lang/Object; 141 L10 142 ASTORE 3 143 L1 144 GOTO L11 145 L2 146 LINENUMBER 44 L2 147 ASTORE 4 148 L12 149 LINENUMBER 45 L12 150 GETSTATIC kotlin/Result.Companion : Lkotlin/Result$Companion; 151 ASTORE 5 152 L13 153 ALOAD 4 154 INVOKESTATIC kotlin/ResultKt.createFailure (Ljava/lang/Throwable;)Ljava/lang/Object; 155 INVOKESTATIC kotlin/Result.constructor-impl (Ljava/lang/Object;)Ljava/lang/Object; 156 L14 157 ASTORE 3 158 L15 159 LINENUMBER 40 L15 160 L11 161 ALOAD 3 162 ASTORE 2 163 L16 164 LINENUMBER 47 L16 165 ALOAD 0 166 GETFIELD f_104_under_the_hood/s_1/MyFunctionContinuation.completion : Lkotlin/coroutines/Continuation; 167 ALOAD 2 168 INVOKEINTERFACE kotlin/coroutines/Continuation.resumeWith (Ljava/lang/Object;)V (itf) 169 L17 170 LINENUMBER 48 L17 171 RETURN 172 L18 173 LOCALVARIABLE r Ljava/lang/Object; L6 L10 3 174 LOCALVARIABLE e Ljava/lang/Throwable; L12 L15 4 175 LOCALVARIABLE res Ljava/lang/Object; L16 L18 2 176 LOCALVARIABLE this Lf_104_under_the_hood/s_1/MyFunctionContinuation; L3 L18 0 177 LOCALVARIABLE result Ljava/lang/Object; L3 L18 1 178 MAXSTACK = 4 179 MAXLOCALS = 6 180 181 // access flags 0x12 182 // signature Lkotlin/coroutines/Continuation<Lkotlin/Unit;>; 183 // declaration: completion extends kotlin.coroutines.Continuation<kotlin.Unit> 184 private final Lkotlin/coroutines/Continuation; completion 185 @Lorg/jetbrains/annotations/NotNull;() // invisible 186 187 // access flags 0x11 188 // signature ()Lkotlin/coroutines/Continuation<Lkotlin/Unit;>; 189 // declaration: kotlin.coroutines.Continuation<kotlin.Unit> getCompletion() 190 public final getCompletion()Lkotlin/coroutines/Continuation; 191 @Lorg/jetbrains/annotations/NotNull;() // invisible 192 L0 193 LINENUMBER 30 L0 194 ALOAD 0 195 GETFIELD f_104_under_the_hood/s_1/MyFunctionContinuation.completion : Lkotlin/coroutines/Continuation; 196 ARETURN 197 L1 198 LOCALVARIABLE this Lf_104_under_the_hood/s_1/MyFunctionContinuation; L0 L1 0 199 MAXSTACK = 1 200 MAXLOCALS = 1 201 202 // access flags 0x1 203 // signature (Lkotlin/coroutines/Continuation<-Lkotlin/Unit;>;)V 204 // declaration: void <init>(kotlin.coroutines.Continuation<? super kotlin.Unit>) 205 public <init>(Lkotlin/coroutines/Continuation;)V 206 // annotable parameter count: 1 (visible) 207 // annotable parameter count: 1 (invisible) 208 @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 209 L0 210 ALOAD 1 211 LDC "completion" 212 INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkNotNullParameter (Ljava/lang/Object;Ljava/lang/String;)V 213 L1 214 LINENUMBER 29 L1 215 ALOAD 0 216 INVOKESPECIAL java/lang/Object.<init> ()V 217 ALOAD 0 218 ALOAD 1 219 PUTFIELD f_104_under_the_hood/s_1/MyFunctionContinuation.completion : Lkotlin/coroutines/Continuation; 220 RETURN 221 L2 222 LOCALVARIABLE this Lf_104_under_the_hood/s_1/MyFunctionContinuation; L0 L2 0 223 LOCALVARIABLE completion Lkotlin/coroutines/Continuation; L0 L2 1 224 MAXSTACK = 2 225 MAXLOCALS = 2 226 227 @Lkotlin/Metadata;(mv={1, 6, 0}, k=1, d1={"\u0000,\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\u0010\u0002\n\u0002\b\u0005\n\u0002\u0018\u0002\n\u0002\b\u0003\n\u0002\u0010\u0008\n\u0002\b\u0005\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0007\u0018\u00002\u0008\u0012\u0004\u0012\u00020\u00020\u0001B\u0013\u0012\u000c\u0010\u0003\u001a\u0008\u0012\u0004\u0012\u00020\u00020\u0001\u00a2\u0006\u0002\u0010\u0004J\u001e\u0010\u0018\u001a\u00020\u00022\u000c\u0010\u0011\u001a\u0008\u0012\u0004\u0012\u00020\u00020\u0012H\u0016\u00f8\u0001\u0000\u00a2\u0006\u0002\u0010\u0019R\u0017\u0010\u0003\u001a\u0008\u0012\u0004\u0012\u00020\u00020\u0001\u00a2\u0006\u0008\n\u0000\u001a\u0004\u0008\u0005\u0010\u0006R\u0014\u0010\u0007\u001a\u00020\u00088VX\u0096\u0004\u00a2\u0006\u0006\u001a\u0004\u0008\u0009\u0010\nR\u001a\u0010\u000b\u001a\u00020\u000cX\u0086\u000e\u00a2\u0006\u000e\n\u0000\u001a\u0004\u0008\r\u0010\u000e\"\u0004\u0008\u000f\u0010\u0010R+\u0010\u0011\u001a\n\u0012\u0004\u0012\u00020\u0013\u0018\u00010\u0012X\u0086\u000e\u00f8\u0001\u0000\u00f8\u0001\u0001\u00f8\u0001\u0002\u00a2\u0006\u000e\n\u0000\u001a\u0004\u0008\u0014\u0010\u0015\"\u0004\u0008\u0016\u0010\u0017\u0082\u0002\u000f\n\u0002\b\u0019\n\u0005\u0008\u00a1\u001e0\u0001\n\u0002\b!\u00a8\u0006\u001a"}, d2={"Lf_104_under_the_hood/s_1/MyFunctionContinuation;", "Lkotlin/coroutines/Continuation;", "", "completion", "(Lkotlin/coroutines/Continuation;)V", "getCompletion", "()Lkotlin/coroutines/Continuation;", "context", "Lkotlin/coroutines/CoroutineContext;", "getContext", "()Lkotlin/coroutines/CoroutineContext;", "label", "", "getLabel", "()I", "setLabel", "(I)V", "result", "Lkotlin/Result;", "", "getResult-xLWZpok", "()Lkotlin/Result;", "setResult", "(Lkotlin/Result;)V", "resumeWith", "(Ljava/lang/Object;)V", "KotlinCoroutines.main"}) 228 // compiled from: 1.kt 229} 230 231 232// ================f_104_under_the_hood/s_1/_1Kt.class ================= 233// class version 52.0 (52) 234// access flags 0x31 235public final class f_104_under_the_hood/s_1/_1Kt { 236 237 238 // access flags 0x19 239 // signature (Lkotlin/coroutines/Continuation<-Lkotlin/Unit;>;)Ljava/lang/Object; 240 // declaration: myFunction(kotlin.coroutines.Continuation<? super kotlin.Unit>) 241 public final static myFunction(Lkotlin/coroutines/Continuation;)Ljava/lang/Object; 242 @Lorg/jetbrains/annotations/NotNull;() // invisible 243 // annotable parameter count: 1 (visible) 244 // annotable parameter count: 1 (invisible) 245 @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 246 L0 247 ALOAD 0 248 LDC "continuation" 249 INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkNotNullParameter (Ljava/lang/Object;Ljava/lang/String;)V 250 L1 251 LINENUMBER 12 L1 252 ALOAD 0 253 DUP 254 INSTANCEOF f_104_under_the_hood/s_1/MyFunctionContinuation 255 IFNE L2 256 POP 257 ACONST_NULL 258 L2 259 CHECKCAST f_104_under_the_hood/s_1/MyFunctionContinuation 260 DUP 261 IFNONNULL L3 262 L4 263 POP 264 L5 265 LINENUMBER 13 L5 266 NEW f_104_under_the_hood/s_1/MyFunctionContinuation 267 DUP 268 ALOAD 0 269 INVOKESPECIAL f_104_under_the_hood/s_1/MyFunctionContinuation.<init> (Lkotlin/coroutines/Continuation;)V 270 L3 271 LINENUMBER 12 L3 272 ASTORE 1 273 L6 274 LINENUMBER 15 L6 275 ALOAD 1 276 INVOKEVIRTUAL f_104_under_the_hood/s_1/MyFunctionContinuation.getLabel ()I 277 IFNE L7 278 L8 279 LINENUMBER 16 L8 280 LDC "Before" 281 ASTORE 2 282 L9 283 GETSTATIC java/lang/System.out : Ljava/io/PrintStream; 284 ALOAD 2 285 INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V 286 L10 287 L11 288 LINENUMBER 17 L11 289 ALOAD 1 290 ICONST_1 291 INVOKEVIRTUAL f_104_under_the_hood/s_1/MyFunctionContinuation.setLabel (I)V 292 L12 293 LINENUMBER 18 L12 294 LDC 1000 295 ALOAD 1 296 CHECKCAST kotlin/coroutines/Continuation 297 INVOKESTATIC f_104_under_the_hood/s_1/_1Kt.delay (JLkotlin/coroutines/Continuation;)Ljava/lang/Object; 298 GETSTATIC f_104_under_the_hood/s_1/_1Kt.COROUTINE_SUSPENDED : Ljava/lang/Object; 299 INVOKESTATIC kotlin/jvm/internal/Intrinsics.areEqual (Ljava/lang/Object;Ljava/lang/Object;)Z 300 IFEQ L7 301 L13 302 LINENUMBER 19 L13 303 GETSTATIC f_104_under_the_hood/s_1/_1Kt.COROUTINE_SUSPENDED : Ljava/lang/Object; 304 ARETURN 305 L7 306 LINENUMBER 22 L7 307 ALOAD 1 308 INVOKEVIRTUAL f_104_under_the_hood/s_1/MyFunctionContinuation.getLabel ()I 309 ICONST_1 310 IF_ICMPNE L14 311 L15 312 LINENUMBER 23 L15 313 LDC "After" 314 ASTORE 2 315 L16 316 GETSTATIC java/lang/System.out : Ljava/io/PrintStream; 317 ALOAD 2 318 INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V 319 L17 320 L18 321 LINENUMBER 24 L18 322 GETSTATIC kotlin/Unit.INSTANCE : Lkotlin/Unit; 323 ARETURN 324 L14 325 LINENUMBER 26 L14 326 LDC "Impossible" 327 ASTORE 2 328 L19 329 NEW java/lang/IllegalStateException 330 DUP 331 ALOAD 2 332 INVOKEVIRTUAL java/lang/Object.toString ()Ljava/lang/String; 333 INVOKESPECIAL java/lang/IllegalStateException.<init> (Ljava/lang/String;)V 334 CHECKCAST java/lang/Throwable 335 ATHROW 336 L20 337 LOCALVARIABLE continuation Lf_104_under_the_hood/s_1/MyFunctionContinuation; L6 L20 1 338 LOCALVARIABLE continuation Lkotlin/coroutines/Continuation; L0 L20 0 339 MAXSTACK = 3 340 MAXLOCALS = 3 341 342 // access flags 0x1A 343 private final static Ljava/util/concurrent/ScheduledExecutorService; executor 344 345 // access flags 0x19 346 // signature (JLkotlin/coroutines/Continuation<-Lkotlin/Unit;>;)Ljava/lang/Object; 347 // declaration: delay(long, kotlin.coroutines.Continuation<? super kotlin.Unit>) 348 public final static delay(JLkotlin/coroutines/Continuation;)Ljava/lang/Object; 349 @Lorg/jetbrains/annotations/NotNull;() // invisible 350 // annotable parameter count: 2 (visible) 351 // annotable parameter count: 2 (invisible) 352 @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1 353 L0 354 ALOAD 2 355 LDC "continuation" 356 INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkNotNullParameter (Ljava/lang/Object;Ljava/lang/String;)V 357 L1 358 LINENUMBER 58 L1 359 GETSTATIC f_104_under_the_hood/s_1/_1Kt.executor : Ljava/util/concurrent/ScheduledExecutorService; 360 NEW f_104_under_the_hood/s_1/_1Kt$delay$1 361 DUP 362 ALOAD 2 363 INVOKESPECIAL f_104_under_the_hood/s_1/_1Kt$delay$1.<init> (Lkotlin/coroutines/Continuation;)V 364 CHECKCAST java/lang/Runnable 365 L2 366 LINENUMBER 60 L2 367 LLOAD 0 368 GETSTATIC java/util/concurrent/TimeUnit.MILLISECONDS : Ljava/util/concurrent/TimeUnit; 369 L3 370 LINENUMBER 58 L3 371 INVOKEINTERFACE java/util/concurrent/ScheduledExecutorService.schedule (Ljava/lang/Runnable;JLjava/util/concurrent/TimeUnit;)Ljava/util/concurrent/ScheduledFuture; (itf) 372 POP 373 L4 374 LINENUMBER 61 L4 375 GETSTATIC f_104_under_the_hood/s_1/_1Kt.COROUTINE_SUSPENDED : Ljava/lang/Object; 376 ARETURN 377 L5 378 LOCALVARIABLE timeMillis J L0 L5 0 379 LOCALVARIABLE continuation Lkotlin/coroutines/Continuation; L0 L5 2 380 MAXSTACK = 5 381 MAXLOCALS = 3 382 383 // access flags 0x19 384 public final static main()V 385 L0 386 LINENUMBER 65 L0 387 NEW f_104_under_the_hood/s_1/_1Kt$main$EMPTY_CONTINUATION$1 388 DUP 389 INVOKESPECIAL f_104_under_the_hood/s_1/_1Kt$main$EMPTY_CONTINUATION$1.<init> ()V 390 ASTORE 0 391 L1 392 LINENUMBER 73 L1 393 ALOAD 0 394 CHECKCAST kotlin/coroutines/Continuation 395 INVOKESTATIC f_104_under_the_hood/s_1/_1Kt.myFunction (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; 396 POP 397 L2 398 LINENUMBER 74 L2 399 LDC 2000 400 INVOKESTATIC java/lang/Thread.sleep (J)V 401 L3 402 LINENUMBER 76 L3 403 RETURN 404 L4 405 LOCALVARIABLE EMPTY_CONTINUATION Lf_104_under_the_hood/s_1/_1Kt$main$EMPTY_CONTINUATION$1; L1 L4 0 406 MAXSTACK = 2 407 MAXLOCALS = 1 408 409 // access flags 0x1009 410 public static synthetic main([Ljava/lang/String;)V 411 INVOKESTATIC f_104_under_the_hood/s_1/_1Kt.main ()V 412 RETURN 413 MAXSTACK = 0 414 MAXLOCALS = 1 415 416 // access flags 0x1A 417 private final static Ljava/lang/Object; COROUTINE_SUSPENDED 418 @Lorg/jetbrains/annotations/NotNull;() // invisible 419 420 // access flags 0x19 421 public final static getCOROUTINE_SUSPENDED()Ljava/lang/Object; 422 @Lorg/jetbrains/annotations/NotNull;() // invisible 423 L0 424 LINENUMBER 78 L0 425 GETSTATIC f_104_under_the_hood/s_1/_1Kt.COROUTINE_SUSPENDED : Ljava/lang/Object; 426 ARETURN 427 L1 428 MAXSTACK = 1 429 MAXLOCALS = 0 430 431 // access flags 0x8 432 static <clinit>()V 433 L0 434 LINENUMBER 52 L0 435 L1 436 LINENUMBER 53 L1 437 GETSTATIC f_104_under_the_hood/s_1/_1Kt$executor$1.INSTANCE : Lf_104_under_the_hood/s_1/_1Kt$executor$1; 438 CHECKCAST java/util/concurrent/ThreadFactory 439 INVOKESTATIC java/util/concurrent/Executors.newSingleThreadScheduledExecutor (Ljava/util/concurrent/ThreadFactory;)Ljava/util/concurrent/ScheduledExecutorService; 440 PUTSTATIC f_104_under_the_hood/s_1/_1Kt.executor : Ljava/util/concurrent/ScheduledExecutorService; 441 L2 442 LINENUMBER 78 L2 443 NEW java/lang/Object 444 DUP 445 INVOKESPECIAL java/lang/Object.<init> ()V 446 PUTSTATIC f_104_under_the_hood/s_1/_1Kt.COROUTINE_SUSPENDED : Ljava/lang/Object; 447 RETURN 448 MAXSTACK = 2 449 MAXLOCALS = 0 450 451 @Lkotlin/Metadata;(mv={1, 6, 0}, k=2, d1={"\u0000$\n\u0000\n\u0002\u0010\u0000\n\u0002\b\u0003\n\u0002\u0018\u0002\n\u0002\b\u0003\n\u0002\u0010\u0009\n\u0000\n\u0002\u0018\u0002\n\u0002\u0010\u0002\n\u0002\b\u0003\u001a\u001c\u0010\u0007\u001a\u00020\u00012\u0006\u0010\u0008\u001a\u00020\u00092\u000c\u0010\n\u001a\u0008\u0012\u0004\u0012\u00020\u000c0\u000b\u001a\u0006\u0010\r\u001a\u00020\u000c\u001a\u0014\u0010\u000e\u001a\u00020\u00012\u000c\u0010\n\u001a\u0008\u0012\u0004\u0012\u00020\u000c0\u000b\"\u0011\u0010\u0000\u001a\u00020\u0001\u00a2\u0006\u0008\n\u0000\u001a\u0004\u0008\u0002\u0010\u0003\"\u0016\u0010\u0004\u001a\n \u0006*\u0004\u0018\u00010\u00050\u0005X\u0082\u0004\u00a2\u0006\u0002\n\u0000\u00a8\u0006\u000f"}, d2={"COROUTINE_SUSPENDED", "", "getCOROUTINE_SUSPENDED", "()Ljava/lang/Object;", "executor", "Ljava/util/concurrent/ScheduledExecutorService;", "kotlin.jvm.PlatformType", "delay", "timeMillis", "", "continuation", "Lkotlin/coroutines/Continuation;", "", "main", "myFunction", "KotlinCoroutines.main"}) 452 // access flags 0x18 453 final static INNERCLASS f_104_under_the_hood/s_1/_1Kt$delay$1 null null 454 // access flags 0x19 455 public final static INNERCLASS f_104_under_the_hood/s_1/_1Kt$main$EMPTY_CONTINUATION$1 null null 456 // access flags 0x18 457 final static INNERCLASS f_104_under_the_hood/s_1/_1Kt$executor$1 null null 458 // compiled from: 1.kt 459} 460 461 462// ================f_104_under_the_hood/s_1/_1Kt$delay$1.class ================= 463// class version 52.0 (52) 464// access flags 0x30 465final class f_104_under_the_hood/s_1/_1Kt$delay$1 implements java/lang/Runnable { 466 467 468 // access flags 0x11 469 public final run()V 470 L0 471 LINENUMBER 59 L0 472 ALOAD 0 473 GETFIELD f_104_under_the_hood/s_1/_1Kt$delay$1.$continuation : Lkotlin/coroutines/Continuation; 474 ASTORE 1 475 GETSTATIC kotlin/Unit.INSTANCE : Lkotlin/Unit; 476 ASTORE 2 477 L1 478 ALOAD 1 479 GETSTATIC kotlin/Result.Companion : Lkotlin/Result$Companion; 480 POP 481 ALOAD 2 482 INVOKESTATIC kotlin/Result.constructor-impl (Ljava/lang/Object;)Ljava/lang/Object; 483 L2 484 INVOKEINTERFACE kotlin/coroutines/Continuation.resumeWith (Ljava/lang/Object;)V (itf) 485 L3 486 LINENUMBER 60 L3 487 RETURN 488 L4 489 LOCALVARIABLE this Lf_104_under_the_hood/s_1/_1Kt$delay$1; L0 L4 0 490 MAXSTACK = 2 491 MAXLOCALS = 3 492 493 // access flags 0x0 494 <init>(Lkotlin/coroutines/Continuation;)V 495 ALOAD 0 496 ALOAD 1 497 PUTFIELD f_104_under_the_hood/s_1/_1Kt$delay$1.$continuation : Lkotlin/coroutines/Continuation; 498 ALOAD 0 499 INVOKESPECIAL java/lang/Object.<init> ()V 500 RETURN 501 MAXSTACK = 2 502 MAXLOCALS = 2 503 504 // access flags 0x1010 505 final synthetic Lkotlin/coroutines/Continuation; $continuation 506 507 @Lkotlin/Metadata;(mv={1, 6, 0}, k=3, d1={"\u0000\u0008\n\u0000\n\u0002\u0010\u0002\n\u0000\u0010\u0000\u001a\u00020\u0001H\n\u00a2\u0006\u0002\u0008\u0002"}, d2={"<anonymous>", "", "run"}) 508 OUTERCLASS f_104_under_the_hood/s_1/_1Kt delay (JLkotlin/coroutines/Continuation;)Ljava/lang/Object; 509 // access flags 0x18 510 final static INNERCLASS f_104_under_the_hood/s_1/_1Kt$delay$1 null null 511 // compiled from: 1.kt 512} 513 514 515// ================f_104_under_the_hood/s_1/_1Kt$main$EMPTY_CONTINUATION$1.class ================= 516// class version 52.0 (52) 517// access flags 0x31 518// signature Ljava/lang/Object;Lkotlin/coroutines/Continuation<Lkotlin/Unit;>; 519// declaration: f_104_under_the_hood/s_1/_1Kt$main$EMPTY_CONTINUATION$1 implements kotlin.coroutines.Continuation<kotlin.Unit> 520public final class f_104_under_the_hood/s_1/_1Kt$main$EMPTY_CONTINUATION$1 implements kotlin/coroutines/Continuation { 521 522 OUTERCLASS f_104_under_the_hood/s_1/_1Kt main ()V 523 524 // access flags 0x12 525 private final Lkotlin/coroutines/CoroutineContext; context 526 @Lorg/jetbrains/annotations/NotNull;() // invisible 527 528 // access flags 0x1 529 public getContext()Lkotlin/coroutines/CoroutineContext; 530 @Lorg/jetbrains/annotations/NotNull;() // invisible 531 L0 532 LINENUMBER 66 L0 533 ALOAD 0 534 GETFIELD f_104_under_the_hood/s_1/_1Kt$main$EMPTY_CONTINUATION$1.context : Lkotlin/coroutines/CoroutineContext; 535 ARETURN 536 L1 537 LOCALVARIABLE this Lf_104_under_the_hood/s_1/_1Kt$main$EMPTY_CONTINUATION$1; L0 L1 0 538 MAXSTACK = 1 539 MAXLOCALS = 1 540 541 // access flags 0x1 542 public resumeWith(Ljava/lang/Object;)V 543 // annotable parameter count: 1 (visible) 544 // annotable parameter count: 1 (invisible) 545 @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 546 L0 547 LINENUMBER 71 L0 548 RETURN 549 L1 550 LOCALVARIABLE this Lf_104_under_the_hood/s_1/_1Kt$main$EMPTY_CONTINUATION$1; L0 L1 0 551 LOCALVARIABLE result Ljava/lang/Object; L0 L1 1 552 MAXSTACK = 0 553 MAXLOCALS = 2 554 555 // access flags 0x0 556 <init>()V 557 L0 558 LINENUMBER 65 L0 559 ALOAD 0 560 INVOKESPECIAL java/lang/Object.<init> ()V 561 L1 562 LINENUMBER 67 L1 563 ALOAD 0 564 GETSTATIC kotlin/coroutines/EmptyCoroutineContext.INSTANCE : Lkotlin/coroutines/EmptyCoroutineContext; 565 CHECKCAST kotlin/coroutines/CoroutineContext 566 PUTFIELD f_104_under_the_hood/s_1/_1Kt$main$EMPTY_CONTINUATION$1.context : Lkotlin/coroutines/CoroutineContext; 567 RETURN 568 L2 569 LOCALVARIABLE this Lf_104_under_the_hood/s_1/_1Kt$main$EMPTY_CONTINUATION$1; L0 L2 0 570 MAXSTACK = 2 571 MAXLOCALS = 1 572 573 @Lkotlin/Metadata;(mv={1, 6, 0}, k=1, d1={"\u0000\u001f\n\u0000\n\u0002\u0018\u0002\n\u0002\u0010\u0002\n\u0000\n\u0002\u0018\u0002\n\u0002\u0008\u0004\n\u0002\u0018\u0002\n\u0002\u0008\u0002*\u0001\u0000\u0008\n\u0018\u00002\u0008\u0012\u0004\u0012\u00020\u00020\u0001J\u001e\u0010\u0007\u001a\u00020\u00022\u000c\u0010\u0008\u001a\u0008\u0012\u0004\u0012\u00020\u00020\u0009H\u0016\u00f8\u0001\u0000\u00a2\u0006\u0002\u0010\nR\u0014\u0010\u0003\u001a\u00020\u0004X\u0096\u0004\u00a2\u0006\u0008\n\u0000\u001a\u0004\u0008\u0005\u0010\u0006\u0082\u0002\u0004\n\u0002\u0008\u0019\u00a8\u0006\u000b"}, d2={"f_104_under_the_hood/s_1/_1Kt$main$EMPTY_CONTINUATION$1", "Lkotlin/coroutines/Continuation;", "", "context", "Lkotlin/coroutines/CoroutineContext;", "getContext", "()Lkotlin/coroutines/CoroutineContext;", "resumeWith", "result", "Lkotlin/Result;", "(Ljava/lang/Object;)V", "KotlinCoroutines.main"}) 574 // access flags 0x19 575 public final static INNERCLASS f_104_under_the_hood/s_1/_1Kt$main$EMPTY_CONTINUATION$1 null null 576 // compiled from: 1.kt 577} 578 579 580// ================f_104_under_the_hood/s_1/_1Kt$executor$1.class ================= 581// class version 52.0 (52) 582// access flags 0x30 583final class f_104_under_the_hood/s_1/_1Kt$executor$1 implements java/util/concurrent/ThreadFactory { 584 585 586 // access flags 0x11 587 public final newThread(Ljava/lang/Runnable;)Ljava/lang/Thread; 588 // annotable parameter count: 1 (visible) 589 // annotable parameter count: 1 (invisible) 590 L0 591 LINENUMBER 54 L0 592 NEW java/lang/Thread 593 DUP 594 ALOAD 1 595 LDC "scheduler" 596 INVOKESPECIAL java/lang/Thread.<init> (Ljava/lang/Runnable;Ljava/lang/String;)V 597 ASTORE 2 598 L1 599 ALOAD 2 600 ASTORE 3 601 L2 602 LINENUMBER 80 L2 603 L3 604 ICONST_0 605 ISTORE 4 606 L4 607 LINENUMBER 54 L4 608 ALOAD 3 609 ICONST_1 610 INVOKEVIRTUAL java/lang/Thread.setDaemon (Z)V 611 L5 612 L6 613 L7 614 LINENUMBER 54 L7 615 L8 616 ALOAD 2 617 L9 618 ARETURN 619 L10 620 LOCALVARIABLE $this$apply Ljava/lang/Thread; L3 L6 3 621 LOCALVARIABLE $i$a$-apply-_1Kt$executor$1$1 I L4 L6 4 622 LOCALVARIABLE this Lf_104_under_the_hood/s_1/_1Kt$executor$1; L0 L10 0 623 LOCALVARIABLE it Ljava/lang/Runnable; L0 L10 1 624 MAXSTACK = 4 625 MAXLOCALS = 5 626 627 // access flags 0x0 628 <init>()V 629 ALOAD 0 630 INVOKESPECIAL java/lang/Object.<init> ()V 631 RETURN 632 MAXSTACK = 1 633 MAXLOCALS = 1 634 635 // access flags 0x19 636 public final static Lf_104_under_the_hood/s_1/_1Kt$executor$1; INSTANCE 637 638 // access flags 0x8 639 static <clinit>()V 640 NEW f_104_under_the_hood/s_1/_1Kt$executor$1 641 DUP 642 INVOKESPECIAL f_104_under_the_hood/s_1/_1Kt$executor$1.<init> ()V 643 PUTSTATIC f_104_under_the_hood/s_1/_1Kt$executor$1.INSTANCE : Lf_104_under_the_hood/s_1/_1Kt$executor$1; 644 RETURN 645 MAXSTACK = 2 646 MAXLOCALS = 0 647 648 @Lkotlin/Metadata;(mv={1, 6, 0}, k=3, d1={"\u0000\u0010\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0000\u0010\u0000\u001a\n \u0002*\u0004\u0018\u00010\u00010\u00012\u000e\u0010\u0003\u001a\n \u0002*\u0004\u0018\u00010\u00040\u0004H\n\u00a2\u0006\u0002\u0008\u0005"}, d2={"<anonymous>", "Ljava/lang/Thread;", "kotlin.jvm.PlatformType", "it", "Ljava/lang/Runnable;", "newThread"}) 649 OUTERCLASS f_104_under_the_hood/s_1/_1Kt null 650 // access flags 0x18 651 final static INNERCLASS f_104_under_the_hood/s_1/_1Kt$executor$1 null null 652 // compiled from: 1.kt 653 // debug info: SMAP 6541.kt 655Kotlin 656*S Kotlin 657*F 658+ 1 1.kt 659f_104_under_the_hood/s_1/_1Kt$executor$1 660+ 2 fake.kt 661kotlin/jvm/internal/FakeKt 662*L 6631#1,79:1 6641#2:80 665*E 666 667} 668 669 670// ================META-INF/KotlinCoroutines.main.kotlin_module ================= 671 672 673f_104_under_the_hood.s_1_1Kt"*
1import java.util.concurrent.Executors; 2import java.util.concurrent.ScheduledExecutorService; 3import java.util.concurrent.ThreadFactory; 4import java.util.concurrent.TimeUnit; 5import kotlin.Metadata; 6import kotlin.Result; 7import kotlin.Unit; 8import kotlin.coroutines.Continuation; 9import kotlin.coroutines.CoroutineContext; 10import kotlin.coroutines.EmptyCoroutineContext; 11import kotlin.jvm.internal.Intrinsics; 12import org.jetbrains.annotations.NotNull; 13 14@Metadata( 15 mv = {1, 6, 0}, 16 k = 2, 17 d1 = {"\u0000$\n\u0000\n\u0002\u0010\u0000\n\u0002\b\u0003\n\u0002\u0018\u0002\n\u0002\b\u0003\n\u0002\u0010\t\n\u0000\n\u0002\u0018\u0002\n\u0002\u0010\u0002\n\u0002\b\u0003\u001a\u001c\u0010\u0007\u001a\u00020\u00012\u0006\u0010\b\u001a\u00020\t2\f\u0010\n\u001a\b\u0012\u0004\u0012\u00020\f0\u000b\u001a\u0006\u0010\r\u001a\u00020\f\u001a\u0014\u0010\u000e\u001a\u00020\u00012\f\u0010\n\u001a\b\u0012\u0004\u0012\u00020\f0\u000b\"\u0011\u0010\u0000\u001a\u00020\u0001¢\u0006\b\n\u0000\u001a\u0004\b\u0002\u0010\u0003\"\u0016\u0010\u0004\u001a\n \u0006*\u0004\u0018\u00010\u00050\u0005X\u0082\u0004¢\u0006\u0002\n\u0000¨\u0006\u000f"}, 18 d2 = {"COROUTINE_SUSPENDED", "", "getCOROUTINE_SUSPENDED", "()Ljava/lang/Object;", "executor", "Ljava/util/concurrent/ScheduledExecutorService;", "kotlin.jvm.PlatformType", "delay", "timeMillis", "", "continuation", "Lkotlin/coroutines/Continuation;", "", "main", "myFunction", "KotlinCoroutines.main"} 19) 20public final class _1Kt { 21 private static final ScheduledExecutorService executor; 22 @NotNull 23 private static final Object COROUTINE_SUSPENDED; 24 25 @NotNull 26 public static final Object myFunction(@NotNull Continuation continuation) { 27 Intrinsics.checkNotNullParameter(continuation, "continuation"); 28 Continuation var10000 = continuation; 29 if (!(continuation instanceof MyFunctionContinuation)) { 30 var10000 = null; 31 } 32 33 MyFunctionContinuation var3 = (MyFunctionContinuation)var10000; 34 if (var3 == null) { 35 var3 = new MyFunctionContinuation(continuation); 36 } 37 38 MyFunctionContinuation continuation = var3; 39 String var2; 40 if (continuation.getLabel() == 0) { 41 var2 = "Before"; 42 System.out.println(var2); 43 continuation.setLabel(1); 44 if (Intrinsics.areEqual(delay(1000L, (Continuation)continuation), COROUTINE_SUSPENDED)) { 45 return COROUTINE_SUSPENDED; 46 } 47 } 48 49 if (continuation.getLabel() == 1) { 50 var2 = "After"; 51 System.out.println(var2); 52 return Unit.INSTANCE; 53 } else { 54 var2 = "Impossible"; 55 throw (Throwable)(new IllegalStateException(var2.toString())); 56 } 57 } 58 59 @NotNull 60 public static final Object delay(long timeMillis, @NotNull final Continuation continuation) { 61 Intrinsics.checkNotNullParameter(continuation, "continuation"); 62 executor.schedule((Runnable)(new Runnable() { 63 public final void run() { 64 Continuation var1 = continuation; 65 Unit var2 = Unit.INSTANCE; 66 Result.Companion var10001 = Result.Companion; 67 var1.resumeWith(Result.constructor-impl(var2)); 68 } 69 }), timeMillis, TimeUnit.MILLISECONDS); 70 return COROUTINE_SUSPENDED; 71 } 72 73 public static final void main() { 74 <undefinedtype> EMPTY_CONTINUATION = new Continuation() { 75 @NotNull 76 private final CoroutineContext context; 77 78 @NotNull 79 public CoroutineContext getContext() { 80 return this.context; 81 } 82 83 public void resumeWith(@NotNull Object result) { 84 } 85 86 { 87 this.context = (CoroutineContext)EmptyCoroutineContext.INSTANCE; 88 } 89 }; 90 myFunction((Continuation)EMPTY_CONTINUATION); 91 Thread.sleep(2000L); 92 } 93 94 // $FF: synthetic method 95 public static void main(String[] var0) { 96 main(); 97 } 98 99 @NotNull 100 public static final Object getCOROUTINE_SUSPENDED() { 101 return COROUTINE_SUSPENDED; 102 } 103 104 static { 105 executor = Executors.newSingleThreadScheduledExecutor((ThreadFactory)null.INSTANCE); 106 COROUTINE_SUSPENDED = new Object(); 107 } 108} 109// MyFunctionContinuation.java 110package f_104_under_the_hood.s_1; 111 112import kotlin.Metadata; 113import kotlin.Result; 114import kotlin.ResultKt; 115import kotlin.Unit; 116import kotlin.coroutines.Continuation; 117import kotlin.coroutines.CoroutineContext; 118import kotlin.jvm.internal.Intrinsics; 119import org.jetbrains.annotations.NotNull; 120import org.jetbrains.annotations.Nullable; 121 122@Metadata( 123 mv = {1, 6, 0}, 124 k = 1, 125 d1 = {"\u0000,\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\u0010\u0002\n\u0002\b\u0005\n\u0002\u0018\u0002\n\u0002\b\u0003\n\u0002\u0010\b\n\u0002\b\u0005\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0007\u0018\u00002\b\u0012\u0004\u0012\u00020\u00020\u0001B\u0013\u0012\f\u0010\u0003\u001a\b\u0012\u0004\u0012\u00020\u00020\u0001¢\u0006\u0002\u0010\u0004J\u001e\u0010\u0018\u001a\u00020\u00022\f\u0010\u0011\u001a\b\u0012\u0004\u0012\u00020\u00020\u0012H\u0016ø\u0001\u0000¢\u0006\u0002\u0010\u0019R\u0017\u0010\u0003\u001a\b\u0012\u0004\u0012\u00020\u00020\u0001¢\u0006\b\n\u0000\u001a\u0004\b\u0005\u0010\u0006R\u0014\u0010\u0007\u001a\u00020\b8VX\u0096\u0004¢\u0006\u0006\u001a\u0004\b\t\u0010\nR\u001a\u0010\u000b\u001a\u00020\fX\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\r\u0010\u000e\"\u0004\b\u000f\u0010\u0010R+\u0010\u0011\u001a\n\u0012\u0004\u0012\u00020\u0013\u0018\u00010\u0012X\u0086\u000eø\u0001\u0000ø\u0001\u0001ø\u0001\u0002¢\u0006\u000e\n\u0000\u001a\u0004\b\u0014\u0010\u0015\"\u0004\b\u0016\u0010\u0017\u0082\u0002\u000f\n\u0002\b\u0019\n\u0005\b¡\u001e0\u0001\n\u0002\b!¨\u0006\u001a"}, 126 d2 = {"Lf_104_under_the_hood/s_1/MyFunctionContinuation;", "Lkotlin/coroutines/Continuation;", "", "completion", "(Lkotlin/coroutines/Continuation;)V", "getCompletion", "()Lkotlin/coroutines/Continuation;", "context", "Lkotlin/coroutines/CoroutineContext;", "getContext", "()Lkotlin/coroutines/CoroutineContext;", "label", "", "getLabel", "()I", "setLabel", "(I)V", "result", "Lkotlin/Result;", "", "getResult-xLWZpok", "()Lkotlin/Result;", "setResult", "(Lkotlin/Result;)V", "resumeWith", "(Ljava/lang/Object;)V", "KotlinCoroutines.main"} 127) 128public final class MyFunctionContinuation implements Continuation { 129 private int label; 130 @Nullable 131 private Result result; 132 @NotNull 133 private final Continuation completion; 134 135 @NotNull 136 public CoroutineContext getContext() { 137 return this.completion.getContext(); 138 } 139 140 public final int getLabel() { 141 return this.label; 142 } 143 144 public final void setLabel(int var1) { 145 this.label = var1; 146 } 147 148 @Nullable 149 public final Result getResult_xLWZpok/* $FF was: getResult-xLWZpok*/() { 150 return this.result; 151 } 152 153 public final void setResult(@Nullable Result var1) { 154 this.result = var1; 155 } 156 157 public void resumeWith(@NotNull Object result) { 158 this.result = Result.box-impl(result); 159 160 Object r; 161 try { 162 r = _1Kt.myFunction((Continuation)this); 163 if (Intrinsics.areEqual(r, _1Kt.getCOROUTINE_SUSPENDED())) { 164 return; 165 } 166 167 Result.Companion var4 = Result.Companion; 168 if (r == null) { 169 throw new NullPointerException("null cannot be cast to non-null type kotlin.Unit"); 170 } 171 172 Unit var7 = (Unit)r; 173 r = Result.constructor-impl(var7); 174 } catch (Throwable var6) { 175 Result.Companion var5 = Result.Companion; 176 r = Result.constructor-impl(ResultKt.createFailure(var6)); 177 } 178 179 this.completion.resumeWith(r); 180 } 181 182 @NotNull 183 public final Continuation getCompletion() { 184 return this.completion; 185 } 186 187 public MyFunctionContinuation(@NotNull Continuation completion) { 188 Intrinsics.checkNotNullParameter(completion, "completion"); 189 super(); 190 this.completion = completion; 191 } 192}

理解 Kotlin 协程

带有状态和恢复值的函数