Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое однопоточность
Однопоточность (single-threaded) — это модель выполнения, при которой приложение выполняет только один процесс за раз в главном потоке. Dart и Flutter используют однопоточную модель с асинхронным программированием.
Основные концепции
Однопоточность означает:
- В один момент времени выполняется только одна операция
- Нет конкурентного доступа к переменным
- Нет race conditions
- Нет deadlocks
- Но есть заблокирование UI при долгих операциях
void main() {
// Dart выполняет код последовательно
print("1"); // выполнится первым
print("2"); // выполнится вторым
print("3"); // выполнится третьим
// Результат: 1, 2, 3
}
Как это работает в Dart
Event Loop (Цикл событий):
// Dart использует Event Loop для управления асинхронностью
void main() {
print("Start");
// Микротаски (микротаски очередь)
Future.microtask(() => print("Microtask"));
// Обычные асинхронные операции (макротаски очередь)
Future.delayed(Duration.zero, () => print("Future"));
print("End");
}
// Результат:
// Start
// End
// Microtask
// Future
Event Loop в деталях
// 1. Выполни синхронный код (главный поток)
void main() {
print("A"); // 1. Выполнится сразу
// 2. Добавить в микротаски
Future.microtask(() => print("B"));
// 3. Добавить в макротаски
Future(() => print("C"));
print("D"); // 2. Выполнится сразу
}
// Порядок выполнения:
// A (синхронный код)
// D (синхронный код)
// B (микротаски)
// C (макротаски)
Проблема: блокирование UI
// ❌ ПЛОХО: долгая операция блокирует UI
void main() {
print("Start");
// Долгая синхронная операция
var sum = 0;
for (int i = 0; i < 1000000000; i++) {
sum += i;
}
print("End: $sum");
// Весь UI заморожен во время цикла!
}
// ✅ ХОРОШО: использовать асинхронность
Future<void> main() async {
print("Start");
// Отдать управление Event Loop'у
await Future.delayed(Duration.zero);
var sum = 0;
for (int i = 0; i < 1000000000; i++) {
sum += i;
}
print("End: $sum");
// UI остается отзывчивым
}
Flutter и однопоточность
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int counter = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
// ❌ ПЛОХО: блокирует UI
onPressed: () {
// Долгая синхронная операция
for (int i = 0; i < 1000000000; i++) {
counter++;
}
setState(() {});
},
child: Icon(Icons.add),
),
);
}
}
// ✅ ПРАВИЛЬНО: использовать async/await
class _MyAppState extends State<MyApp> {
int counter = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () async {
// Дать UI время отреагировать
await Future.delayed(Duration.zero);
// Теперь можем выполнить операцию
counter++;
setState(() {});
},
child: Icon(Icons.add),
),
);
}
}
Асинхронные операции в однопоточной среде
// Future — обещание получить результат в будущем
Future<String> fetchData() async {
// Имитация сетевого запроса
await Future.delayed(Duration(seconds: 2));
return "Data loaded";
}
Future<void> main() async {
print("Start");
// await ждет результата, но не блокирует другие операции
var data = await fetchData();
print("Result: $data");
}
Примеры однопоточности в Flutter
// Загрузка данных без блокирования UI
class UserList extends StatefulWidget {
@override
State<UserList> createState() => _UserListState();
}
class _UserListState extends State<UserList> {
late Future<List<User>> futureUsers;
@override
void initState() {
super.initState();
futureUsers = fetchUsers(); // Запускается асинхронно
}
@override
Widget build(BuildContext context) {
return FutureBuilder<List<User>>(
future: futureUsers,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
}
if (snapshot.hasError) {
return Text("Error: ${snapshot.error}");
}
return ListView(
children: snapshot.data!.map((user) => UserTile(user)).toList(),
);
},
);
}
}
Future<List<User>> fetchUsers() async {
final response = await http.get(Uri.parse("https://api.example.com/users"));
// ... парсинг
}
Isolates для параллельных вычислений
Когда однопоточности недостаточно, используют Isolates:
// Isolate — отдельный поток с собственным Event Loop'ом
import 'dart:isolate';
// Функция для выполнения в отдельном потоке
Future<int> computeSum(int limit) async {
var sum = 0;
for (int i = 0; i < limit; i++) {
sum += i;
}
return sum;
}
Future<void> main() async {
print("Start");
// Запустить в отдельном Isolate
final result = await Isolate.run(() => computeSum(1000000000));
print("Sum: $result");
// UI остается отзывчивым!
}
Сравнение с многопоточностью
Однопоточность (Dart/Flutter):
- ✅ Нет race conditions
- ✅ Нет deadlocks
- ✅ Проще для понимания
- ✅ Меньше bugs
- ❌ Долгие операции блокируют UI
- ❌ Не использует несколько ядер процессора
Многопоточность (Java/Kotlin):
- ✅ Использует несколько ядер
- ✅ Может использовать все ресурсы
- ❌ Race conditions
- ❌ Deadlocks
- ❌ Сложнее для понимания
- ❌ Больше bugs
Лучшие практики в однопоточном Dart
Делай:
- ✅ Используй async/await для асинхронных операций
- ✅ Используй FutureBuilder / StreamBuilder
- ✅ Разбивай долгие операции на части
- ✅ Используй Isolates для тяжелых вычислений
- ✅ Дай Event Loop'у время работать
Избегай:
- ❌ Долгих синхронных операций в main thread
- ❌ Блокирующих циклов
- ❌ Синхронных HTTP запросов
- ❌ Тяжелых вычислений в UI потоке
Практический пример: правильная работа с async
Future<void> loadAndProcess() async {
try {
// 1. Загрузить данные
final data = await fetchData();
// 2. Обработать данные
final processed = await processData(data);
// 3. Обновить UI
setState(() {
myData = processed;
});
} catch (e) {
print("Error: $e");
}
}
// В UI
ElevatedButton(
onPressed: loadAndProcess,
child: Text("Load"),
)
Заключение
Однопоточность в Dart/Flutter — это не ограничение, а особенность дизайна, которая:
- Упрощает разработку
- Убирает целый класс ошибок
- Позволяет написать более надежный код
- Требует понимания асинхронного программирования
Для Flutter разработчика критично понимать Event Loop и как правильно использовать async/await для создания отзывчивых приложений.