Использование нативных корутин в Java

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

Многие современные языки поддерживают работу с корутинами на уровне языка. Java в данный момент не поддерживает корутины, но есть надежды что в будущем все может измениться.

В С++20 планируется ввести поддержку для работы с корутинами.
Используя JNI мы можем писать корутины на С++ и использовать в Java коде.

Рассмотрим какие нативные корутины можно писать и как их использовать в Java коде.

Генератор позволяет создавать последовательность значений определенного типа, при этом значения генерируются лениво и синхронно.

  /* C++ code */
  generator<int> generate(int count) {
    for (int i = 0; i < count; i++) {
       co_yield i;
    }
  }


  /* Java code */
  Generator<Integer> gen1 = Coroutine.yield(5);
  Generator<Float>   gen2 = Coroutine.yield(1f, 5);
  Generator<Double>  gen3 = Coroutine.yield(v -> v * 2, 1d, 5);
		
  for (int item : gen1) {
     System.out.println("yield value: " + item);
  }


Асинхронный Генератор позволяет создавать последовательность значений определенного типа, при этом значения генерируются лениво и асинхронно.

  /* C++ code */
  async_generator<int> generate(int count) {
    for (int i = 0; i < count; i++) {
       co_await 1s;
       co_yield i;
    }
  }


  /* Java code */
  Generator<Integer> gen1 = Coroutine.yieldAsync(5);
  Generator<Float>   gen2 = Coroutine.yieldAsync(1f, 5);
  Generator<Double>  gen3 = Coroutine.yieldAsync(v -> v * 2, 1d, 5);
		
  for (int item : gen1) {
     System.out.println("yield value: " + item);
  }


Задача (Task) производит асинхронное вычисление, которое выполняется лениво, при этом корутина не выполняется, пока задача не запустится явно.

Корутины можно использовать как легковесные потоки. При этом количество запущенных потоков в системе может быть ограничено, например не более 1000. А корутин можно запустить сколько угодно.

При запуске корутины, проверяется готова ли она. Если нет, то корутина приостанавливается и ОС передается обработчик на ее. В этот момент выполниться полезный кусок кода. Когда корутина готова, тогда выполняется возобновление корутины.

  /* C++ code */
  struct awaiter {
     bool await_ready() const { return false; }
     void await_resume() {}

     void await_suspend(std::coroutine_handle<> handler) {
        /* invoke java/jni code */

        if (!handler.done()) {
           handler.resume();
        }
     }
  };

  co_await awaiter{};


Как при запуске потока, корутине можно передать Runnable или Callable.

   /* Java code */
   Coroutine.await(() -> {
      int sum = 5 + 10;
   });

   Task<Integer> task = Coroutine.await(() -> {
      int sum = 5 + 10;
      return sum;
   });


Таймер выполняет приостановку выполнения текущей задачи на требуемую длительность.

   auto operator co_await(const std::chrono::system_clock::duration& duration) {
      return timer{duration};
   }
   
   co_await 10ms;


Можно использовать как замену Thread.sleep().

   Coroutine.await(10, TimeUnit.MILLISECONDS); 


Также корутины можно применять для написания не блокирующего кода для работы с файловой системой, сетью и т.д.

Как можно видеть корутины облегчают написание асинхроного кода, позволяя выполнять части кода не блокируя поток.

Корутины которые планируют завести в С++20, появлятся в виде чистой языковой фичи.
Генераторы, задачи и другие корутиные планируются добавить в стандарт С++23 или позже.
Можно самому писать свои корутины или использовать уже готовой библиотекой, например cppcoro.

Компиляторы MVSC, Clang уже поддерживают корутины как расширение, а GCC только на стадии разработки.
Полный исходной код можно посмотреть на github: code
Источник: https://habr.com/ru/post/474394/


Интересные статьи

Интересные статьи

Здравствуйте дорогие читатели. Этот канал посвящён программированию и робототехнике. И конечно он затрагивает образовательный аспект изучению этих дисциплин.Данная статья...
Привет, Хабр! Представляю вашему вниманию ироничную вариацию на тему семи смертных грехов. На этот раз, в контексте управленческих практик. Перевод статьи Evil Coach. Итак, в ваше...
Здравствуй, Хабр! Данное руководство является первой частью в запланированном цикле статей про такой замечательный фреймворк для тестирования как Jest. Материал будет полезен новичкам...
Многие игроки считают, что XIM Apex — это необнаруживаемое читерское устройство, которое портит видеоигры. Но для людей с нарушениями моторики это единственная возможность играть. Мультиплее...
Вы когда-нибудь задумывались, как браузеры читают и исполняют JavaScript-код? Это выглядит таинственно, но в этом посте вы можете получить представление, что же происходит под капотом. Начнё...