Kotlin 코루틴 원칙에 대한 이해와 생각

먼저 매우 간단한 kotlin 코루틴 코드를 살펴보겠습니다.

fun test4() {
    GlobalScope.launch {
        println("准备执行")
        val value = async {
            println("执行异步")
            1024
        }.await()
        println("执行完毕:${value}")
    }
}

중간에 비동기 실행 기간이 있으며 코드는 다음 작업을 계속 실행하기 전에 이 비동기 실행이 완료될 때까지 기다려야 합니다. 이제 이를 Java로 구현하고 두 개의 Runnable을 사용하여 시뮬레이션해 보겠습니다.

private static final Object COROUTINE_SUSPEND = "suspend";

class MyRunnable implements Runnable {

  	 int label = 0;

     @Override
     public void run() {
         invoke(null);
     }

	// 这段invoke代码就是上面那段了
     public void invoke(Object result) {
         Object value = COROUTINE_SUSPEND;
         checkException(result);
         switch (label) {
             case 0:
                 println("准备执行");
                 value = async(this);
                 label = 1;
                 if (value == COROUTINE_SUSPEND) {
                     return;
                 }
                 break;
             case 1:
                 value = result;
                 break;
         }
         int num = (int) value;
         println("执行完毕:" + num);
     }
 };

  class AsyncRunnable implements Runnable {

       boolean isCompleted;
       MyRunnable otherRunnable;

       public Object myAsync(MyRunnable runnable) {
           otherRunnable = runnable;
           executors.submit(this);
           return COROUTINE_SUSPEND;
       }

       @Override
       public void run() {
           invoke(null);
       }

       private void invoke(Object result) {
           checkException(result);
           println("执行异步");
           int value = 1024;
           isCompleted = true;
           otherRunnable.invoke(value);
        }
    }

	
  private Object async(MyRunnable myRunnable) {
       AsyncRunnable asyncRunnable = new AsyncRunnable();
       return asyncRunnable.myAsync(myRunnable);
   }

사실 아주 간단합니다. 코루틴의 핵심은 함수나 프로그램을 일시 중지했다가 일시 중지된 위치에서 다시 시작할 수 있으며, 이 일시 중지 및 복구는 " 먼저 함수로 돌아가서 다시 시작하는 것입니다. 비동기 완료 후 실행합니다. " , 내부 코드는 실행할 여러 섹션으로 나뉩니다.

지금 바로 다음 코드를 검토하세요. 두 가지 사항이 매우 중요합니다.
(1) MyRunnable은 코루틴의 구현에 따라 비동기 함수가 호출될 때 전달됩니다. 즉, 각 일시 중단 함수에는 숨겨진 매개변수 Continuation이 있습니다. 일반 CPS 변환(계속 통과 스타일). 이 경우 비동기 작업이 완료된 후 바로 지금 MyRunnable 매개 변수의 invoke 메서드를 호출하면 됩니다.
(2) 레이블 변수에 의존하여 실행 지점을 기록하면 다음에 다시 호출할 때 마지막으로 실행된 단계를 알 수 있습니다.분할된 위치는 일시 중단 함수를 호출하고 COROUTINE_SUSPEND 플래그를 반환하는 것입니다.

읽은 후 Kotlin 코드의 컴파일된 바이트 코드를 보면 어떻게 구현되어 있는지 확인할 수 있습니다. 더 일반적으로 이해하려면 숨겨진 연속을 콜백으로 생각할 수 있으며 이는 매우 일반적입니다. Kotlin은 이러한 콜백을 모두 저장하므로 이러한 콜백을 작성할 필요가 없으며 동기처럼 보이는 비동기 코드를 작성할 수 있습니다. 코드 는 ~와 마찬가지로.

그렇다면 매우 중요한 질문이 있는데요 사실 코드를 보면 쓰레드 풀을 사용하든 코틀린 코루틴을 사용하든 효율은 같습니다 그래서 코드의 단순함과 더불어 코틀린을 어떻게 사용하는지 코루틴의 장점을 반영하기 위해서는 ?

코루틴이든 스레드 풀이든 블로킹을 유발하는 IO 작업의 경우 스레드는 필연적으로 차단됩니다. 효율성을 향상시킬 수 있는 것은 원래 Java에서 스레드 블로킹을 유발하는 일부 동작에 대해 kotlin을 사용하는 것입니다 . 대신 코루틴 API를 사용하여 스레드 리소스 사용을 최대화합니다 .

예를 들어:

  1. Thread.sleep 대신 지연을 사용하십시오.
  2. BlockCollection 대신 채널을 사용하십시오.
  3. 스레드의 yield 및 join 대신 kotlin의 yield 및 join을 사용합니다.
  4. Java의 잠금 메커니즘을 코루틴의 Metux로 교체합니다.

Thread.sleep과 같은 메소드의 경우 스레드가 차단되면 스레드가 계속 작동할 수 없으며 작업이 많은 경우 새 스레드를 다시 시작하여 실행할 수만 있으며 스레드가 상대적으로 리소스 집약적인 프로세스라는 것은 모두 알고 있습니다. 많은 메커니즘이 있는데, 코루틴 API는 이러한 차단 방식을 교묘하게 피하고 타이머를 설정한 후 다시 실행하는 지연 방식과 같은 더 가벼운 작업으로 구현합니다. 암호.

추천

출처blog.csdn.net/aa642531/article/details/112055914