← Назад к вопросам

Как создать два потока в Dart?

1.7 Middle🔥 81 комментариев
#Dart#Асинхронность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как создать два потока в Dart?

В Dart многопоточность реализуется через Isolates — отдельные экземпляры виртуальной машины Dart с собственной памятью. Это отличается от потоков в других языках тем, что Isolates полностью изолированы и не делят памяти, что исключает проблемы с race conditions.

Создание простого Isolate

import "dart:isolate";

void isolateFunction() {
  print("Работаю в отдельном isolate");
  for (int i = 0; i < 5; i++) {
    print("Isolate: $i");
  }
}

void main() async {
  print("Главный поток");
  
  // Создаём два isolate
  await Isolate.spawn(isolateFunction, null);
  await Isolate.spawn(isolateFunction, null);
  
  print("Оба isolate запущены");
}

Двусторонняя коммуникация с ReceivePort

Для передачи данных между isolates используются порты:

future isolateTask(SendPort sendPort) async {
  final receivePort = ReceivePort();
  sendPort.send(receivePort.sendPort);

  await for (var message in receivePort) {
    if (message == "exit") {
      receivePort.close();
      break;
    }
    print("Isolate получил: $message");
    final result = message * 2;
    sendPort.send(result);
  }
}

void main() async {
  final receivePort = ReceivePort();
  await Isolate.spawn(isolateTask, receivePort.sendPort);
  
  // Получаем sendPort от isolate
  final isolateSendPort = await receivePort.first;
  
  // Отправляем данные
  isolateSendPort.send(5);
  receivePort.listen((message) {
    print("Главный получил результат: $message");
  });
}

Практический пример: вычисление в фоне

future<int> heavyComputation(int value) async {
  final receivePort = ReceivePort();
  await Isolate.spawn(_compute, receivePort.sendPort);
  
  final isolateSendPort = await receivePort.first;
  isolateSendPort.send(value);
  
  final result = await receivePort.first;
  return result;
}

void _compute(SendPort mainSendPort) async {
  final receivePort = ReceivePort();
  mainSendPort.send(receivePort.sendPort);
  
  await for (var value in receivePort) {
    // Тяжёлые вычисления
    final result = List.generate(1000000, (i) => i).fold<int>(0, (a, b) => a + b);
    mainSendPort.send(result);
  }
}

Использование compute() из Flutter

Для Flutter рекомендуется использовать более простой способ через функцию compute():

import "package:flutter/foundation.dart";

int fibonacci(int n) {
  if (n <= 1) return n;
  return fibonacci(n - 1) + fibonacci(n - 2);
}

volatile main() async {
  // Запускаем вычисления в фоновом isolate
  final result = await compute(fibonacci, 30);
  print("Результат: $result");
}

Ключевые особенности Isolates

  • Полная изоляция — нет общей памяти, нет race conditions
  • Копирование данных — сообщения копируются между isolates
  • Асинхронность — Isolate.spawn() не блокирует главный поток
  • Производительность — создание isolate имеет затраты, используйте для тяжёлых операций

Когда использовать Isolates

  • Долгие вычисления (криптография, обработка данных)
  • Обработка больших файлов
  • Сетевые запросы
  • Тяжёлые операции с JSON/XML

Для простых асинхронных операций используйте async/await и Futures — это более лёгкое решение и выполняется в одном потоке с event loop'ом.

Как создать два потока в Dart? | PrepBro