CINXE.COM

Concurrency | Dart

<!doctype html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="x-ua-compatible" content="ie=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><script>!function(e,t,a,n){e[n]=e[n]||[],e[n].push({"gtm.start":(new Date).getTime(),event:"gtm.js"});var g=t.getElementsByTagName(a)[0],m=t.createElement(a);m.async=!0,m.src="https://www.googletagmanager.com/gtm.js?id=GTM-5VSZM5J",g.parentNode.insertBefore(m,g)}(window,document,"script","dataLayer")</script><meta name="description" content="Use isolates to enable parallel code execution on multiple processor cores."><title>Concurrency | Dart</title><link rel="icon" sizes="64x64" href="/assets/img/logo/dart-64.png" eleventy:ignore><link href="/assets/img/touch-icon-iphone.png" rel="apple-touch-icon" eleventy:ignore><link href="/assets/img/touch-icon-ipad.png" rel="apple-touch-icon" sizes="152x152" eleventy:ignore><link href="/assets/img/touch-icon-iphone-retina.png" rel="apple-touch-icon" sizes="180x180" eleventy:ignore><link href="/assets/img/touch-icon-ipad-retina.png" rel="apple-touch-icon" sizes="167x167" eleventy:ignore><meta name="twitter:card" content="summary"><meta name="twitter:site" content="@dart_lang"><meta name="twitter:title" content="Concurrency in Dart"><meta name="twitter:description" content="Use isolates to enable parallel code execution on multiple processor cores."><meta property="og:title" content="Concurrency in Dart"><meta property="og:description" content="Use isolates to enable parallel code execution on multiple processor cores."><meta property="og:url" content="/language/concurrency/"><meta property="og:image" content="/assets/img/logo/dart-logo-for-shares.png?2" eleventy:ignore><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Google+Sans:wght@400;500;700&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Google+Sans+Display:wght@400&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Google+Sans+Mono:wght@400;500;700&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Google+Sans+Text:wght@400;500;700&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0..1,0" rel="stylesheet"><link rel="stylesheet" href="/assets/css/main.css?v=2"><script src="/assets/js/os-tabs.js?v=2"></script><script src="/assets/js/main.js?v=2"></script><script>!function(e,a,t,n,c,o,s){e.GoogleAnalyticsObject=c,e[c]=e[c]||function(){(e[c].q=e[c].q||[]).push(arguments)},e[c].l=1*new Date,o=a.createElement(t),s=a.getElementsByTagName(t)[0],o.async=1,o.src="//www.google-analytics.com/analytics.js",s.parentNode.insertBefore(o,s)}(window,document,"script",0,"ga"),ga("create","UA-26406144-4","auto"),ga("send","pageview")</script></head><body class="default.html"><a id="skip" href="#site-content-title" tabindex="1">Skip to main content</a><section id="cookie-notice"><div class="container"><p>dart.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic.</p><div class="button-group"><a class="text-button" href="https://policies.google.com/technologies/cookies" target="_blank" rel="noopener">Learn more</a> <button id="cookie-consent" class="filled-button">OK, got it</button></div></div></section><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5VSZM5J" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript><div id="site-banner" role="alert"><p>Announcing Dart 3.7! Find out about updates to the language, analyzer, pub.dev, and more, in the <a href="https://medium.com/dartlang/announcing-dart-3-7-bf864a1b195c" target="_blank">blog post</a>.</p></div><header id="page-header" class="site-header"><nav id="mainnav" class="site-header"><div id="menu-toggle"><span class="material-symbols" title="Toggle side navigation menu." aria-label="Toggle side navigation menu." type="button">menu</span></div><a href="/" class="brand" title="Dart"><img src="/assets/img/logo/logo-white-text.svg" alt="Dart"></a><ul class="navbar"><li><a href="/overview" class="nav-link">Overview</a></li><li class="mainnav__get-started"><a href="/docs" class="nav-link active"><span>Docs</span></a></li><li><a href="/community" class="nav-link">Community</a></li><li><a href="/#try-dart" class="nav-link">Try Dart</a></li><li><a href="/get-dart" class="nav-link">Get Dart</a></li><li class="searchfield"><form action="/search" class="site-header__search form-inline" id="cse-search-box"><input type="hidden" name="cx" value="011220921317074318178:_yy-tmb5t_i"> <input type="hidden" name="ie" value="UTF-8"> <input type="hidden" name="hl" value="en"> <input class="site-header__searchfield form-control search-field" type="search" name="q" id="search-main" autocomplete="off" placeholder="Search" aria-label="Search"></form></li></ul></nav></header><div id="site-below-header"><div id="site-main-row"><div id="sidenav"><form action="/search/" class="site-header__search form-inline"><input class="site-header__searchfield form-control search-field" type="search" name="q" id="search-side" autocomplete="off" placeholder="Search" aria-label="Search"></form><ul class="navbar-nav"><li aria-hidden="true"><div class="sidenav-divider"></div></li><li class="nav-item"><a href="/overview" class="nav-link">Overview</a></li><li class="nav-item"><a href="/community" class="nav-link">Community</a></li><li class="nav-item"><a href="https://dartpad.dev" class="nav-link">Try Dart</a></li><li class="nav-item"><a href="/get-dart" class="nav-link">Get Dart</a></li><li class="nav-item"><a href="/docs" class="nav-link">Docs</a></li><li aria-hidden="true"><div class="sidenav-divider"></div></li></ul><ul class="nav"><li class="nav-item"><button class="nav-link active collapsible" data-toggle="collapse" data-target="#-sidenav-1" role="button" aria-expanded="true" aria-controls="-sidenav-1"><span>Language</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse show" id="-sidenav-1"><li class="nav-item"><a class="nav-link" href="/language"><div><span>Introduction</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-2" role="button" aria-expanded="false" aria-controls="-sidenav-1-2"><span>Syntax basics</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-2"><li class="nav-item"><a class="nav-link" href="/language/variables"><div><span>Variables</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/operators"><div><span>Operators</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/comments"><div><span>Comments</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/metadata"><div><span>Metadata</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/libraries"><div><span>Libraries & imports</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/keywords"><div><span>Keywords</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-3" role="button" aria-expanded="false" aria-controls="-sidenav-1-3"><span>Types</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-3"><li class="nav-item"><a class="nav-link" href="/language/built-in-types"><div><span>Built-in types</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/records"><div><span>Records</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/collections"><div><span>Collections</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/generics"><div><span>Generics</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/typedefs"><div><span>Typedefs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/type-system"><div><span>Type system</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-4" role="button" aria-expanded="false" aria-controls="-sidenav-1-4"><span>Patterns</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-4"><li class="nav-item"><a class="nav-link" href="/language/patterns"><div><span>Overview & usage</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/pattern-types"><div><span>Pattern types</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/dart-patterns-records" target="_blank" rel="noopener"><div><span>Applied tutorial</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="/language/functions"><div><span>Functions</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-6" role="button" aria-expanded="false" aria-controls="-sidenav-1-6"><span>Control flow</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-6"><li class="nav-item"><a class="nav-link" href="/language/loops"><div><span>Loops</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/branches"><div><span>Branches</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/error-handling"><div><span>Error handling</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-7" role="button" aria-expanded="false" aria-controls="-sidenav-1-7"><span>Classes & objects</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-7"><li class="nav-item"><a class="nav-link" href="/language/classes"><div><span>Classes</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/constructors"><div><span>Constructors</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/methods"><div><span>Methods</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/extend"><div><span>Extend a class</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/mixins"><div><span>Mixins</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/enums"><div><span>Enums</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/extension-methods"><div><span>Extension methods</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/extension-types"><div><span>Extension types</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/callable-objects"><div><span>Callable objects</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-8" role="button" aria-expanded="false" aria-controls="-sidenav-1-8"><span>Class modifiers</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-8"><li class="nav-item"><a class="nav-link" href="/language/class-modifiers"><div><span>Overview & usage</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/class-modifiers-for-apis"><div><span>Class modifiers for API maintainers</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/modifier-reference"><div><span>Reference</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link active collapsible" data-toggle="collapse" data-target="#-sidenav-1-9" role="button" aria-expanded="true" aria-controls="-sidenav-1-9"><span>Concurrency</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse show" id="-sidenav-1-9"><li class="nav-item"><a class="nav-link active" href="/language/concurrency"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/async"><div><span>Asynchronous support</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/isolates"><div><span>Isolates</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-10" role="button" aria-expanded="false" aria-controls="-sidenav-1-10"><span>Null safety</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-10"><li class="nav-item"><a class="nav-link" href="/null-safety"><div><span>Sound null safety</span></div></a></li><li class="nav-item"><a class="nav-link" href="/null-safety/migration-guide"><div><span>Migrating to null safety</span></div></a></li><li class="nav-item"><a class="nav-link" href="/null-safety/understanding-null-safety"><div><span>Understanding null safety</span></div></a></li><li class="nav-item"><a class="nav-link" href="/null-safety/unsound-null-safety"><div><span>Unsound null safety</span></div></a></li><li class="nav-item"><a class="nav-link" href="/null-safety/faq"><div><span>FAQ</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-2" role="button" aria-expanded="false" aria-controls="-sidenav-2"><span>Core libraries</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-2"><li class="nav-item"><a class="nav-link" href="/libraries"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-core"><div><span>dart:core</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-async"><div><span>dart:async</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-math"><div><span>dart:math</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-convert"><div><span>dart:convert</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-io"><div><span>dart:io</span></div></a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop"><div><span>dart:js_interop</span></div></a></li><div class="sidenav-divider"></div><li class="nav-item"><a class="nav-link" href="/libraries/collections/iterables"><div><span>Iterable collections</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-2-10" role="button" aria-expanded="false" aria-controls="-sidenav-2-10"><span>Asynchronous programming</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-2-10"><li class="nav-item"><a class="nav-link" href="/libraries/async/async-await"><div><span>Tutorial</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/async/futures-error-handling"><div><span>Futures and error handling</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/async/using-streams"><div><span>Using streams</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/async/creating-streams"><div><span>Creating streams</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-3" role="button" aria-expanded="false" aria-controls="-sidenav-3"><span>Effective Dart</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-3"><li class="nav-item"><a class="nav-link" href="/effective-dart"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/effective-dart/style"><div><span>Style</span></div></a></li><li class="nav-item"><a class="nav-link" href="/effective-dart/documentation"><div><span>Documentation</span></div></a></li><li class="nav-item"><a class="nav-link" href="/effective-dart/usage"><div><span>Usage</span></div></a></li><li class="nav-item"><a class="nav-link" href="/effective-dart/design"><div><span>Design</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-4" role="button" aria-expanded="false" aria-controls="-sidenav-4"><span>Packages</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-4"><li class="nav-item"><a class="nav-link" href="/tools/pub/packages"><div><span>How to use packages</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/useful-packages"><div><span>Commonly used packages</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/create-packages"><div><span>Creating packages</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/publishing"><div><span>Publishing packages</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/writing-package-pages"><div><span>Writing package pages</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/workspaces"><div><span>Workspaces (monorepo support)</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-4-7" role="button" aria-expanded="false" aria-controls="-sidenav-4-7"><span>Package reference</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-4-7"><li class="nav-item"><a class="nav-link" href="/tools/pub/dependencies"><div><span>Dependencies</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/glossary"><div><span>Glossary</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/package-layout"><div><span>Package layout conventions</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/environment-variables"><div><span>Pub environment variables</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/pubspec"><div><span>Pubspec file</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/troubleshoot"><div><span>Troubleshooting pub</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/verified-publishers"><div><span>Verified publishers</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/security-advisories"><div><span>Security advisories</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/versioning"><div><span>Versioning</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/custom-package-repositories"><div><span>Custom package repositories</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="/tools/pub/private-files"><div><span>What not to commit</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-5" role="button" aria-expanded="false" aria-controls="-sidenav-5"><span>Development</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-5"><li class="nav-item"><a class="nav-link" href="/libraries/serialization/json"><div><span>JSON serialization</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/language/number-representation"><div><span>Number representation</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/google-apis"><div><span>Google APIs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/multiplatform-apps"><div><span>Multi-platform apps</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-5-5" role="button" aria-expanded="false" aria-controls="-sidenav-5-5"><span>Command-line & server apps</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-5-5"><li class="nav-item"><a class="nav-link" href="/server"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tutorials/server/get-started"><div><span>Get started</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tutorials/server/cmdline"><div><span>Write command-line apps</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tutorials/server/fetch-data"><div><span>Fetch data from the internet</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tutorials/server/httpserver"><div><span>Write HTTP servers</span></div></a></li><li class="nav-item"><a class="nav-link" href="/server/libraries"><div><span>Libraries & packages</span></div></a></li><li class="nav-item"><a class="nav-link" href="/server/google-cloud"><div><span>Google Cloud</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-5-6" role="button" aria-expanded="false" aria-controls="-sidenav-5-6"><span>Web apps</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-5-6"><li class="nav-item"><a class="nav-link" href="/web"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/web/get-started"><div><span>Get started</span></div></a></li><li class="nav-item"><a class="nav-link" href="/web/deployment"><div><span>Deployment</span></div></a></li><li class="nav-item"><a class="nav-link" href="/web/libraries"><div><span>Libraries & packages</span></div></a></li><li class="nav-item"><a class="nav-link" href="/web/wasm"><div><span>Wasm compilation</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="/libraries/core/environment-declarations"><div><span>Environment declarations</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-6" role="button" aria-expanded="false" aria-controls="-sidenav-6"><span>Interoperability</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-6"><li class="nav-item"><a class="nav-link" href="/interop/c-interop"><div><span>C interop</span></div></a></li><li class="nav-item"><a class="nav-link" href="/interop/objective-c-interop"><div><span>Objective-C & Swift interop</span></div></a></li><li class="nav-item"><a class="nav-link" href="/interop/java-interop"><div><span>Java & Kotlin interop</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-6-4" role="button" aria-expanded="false" aria-controls="-sidenav-6-4"><span>JavaScript interop</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-6-4"><li class="nav-item"><a class="nav-link" href="/interop/js-interop"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop/usage"><div><span>Usage</span></div></a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop/js-types"><div><span>JS types</span></div></a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop/tutorials"><div><span>Tutorials</span></div></a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop/past-js-interop"><div><span>Past JS interop</span></div></a></li><div class="sidenav-divider"></div><li class="nav-item"><a class="nav-link" href="/interop/js-interop/package-web"><div><span>Web interop</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-7" role="button" aria-expanded="false" aria-controls="-sidenav-7"><span>Tools & techniques</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-7"><li class="nav-item"><a class="nav-link" href="/tools"><div><span>Overview</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-7-2" role="button" aria-expanded="false" aria-controls="-sidenav-7-2"><span>Editors & debuggers</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-7-2"><li class="nav-item"><a class="nav-link" href="/tools/jetbrains-plugin"><div><span>IntelliJ & Android Studio</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/vs-code"><div><span>VS Code</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-devtools"><div><span>Dart DevTools</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-7-2-4" role="button" aria-expanded="false" aria-controls="-sidenav-7-2-4"><span>DartPad</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-7-2-4"><li class="nav-item"><a class="nav-link" href="/tools/dartpad"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dartpad/troubleshoot"><div><span>Troubleshooting DartPad</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-7-3" role="button" aria-expanded="false" aria-controls="-sidenav-7-3"><span>Command-line tools</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-7-3"><li class="nav-item"><button class="nav-link collapsible" data-toggle="collapse" data-target="#-sidenav-7-3-1" role="button" aria-expanded="true" aria-controls="-sidenav-7-3-1"><span>Dart SDK</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse show" id="-sidenav-7-3-1"><li class="nav-item"><a class="nav-link" href="/tools/sdk"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-tool"><div><span>dart</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-analyze"><div><span>dart analyze</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-compile"><div><span>dart compile</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-create"><div><span>dart create</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-doc"><div><span>dart doc</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-fix"><div><span>dart fix</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-format"><div><span>dart format</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-info"><div><span>dart info</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/cmd"><div><span>dart pub</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-run"><div><span>dart run</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-test"><div><span>dart test</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dartaotruntime"><div><span>dartaotruntime</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/experiment-flags"><div><span>Experiment flags</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible" data-toggle="collapse" data-target="#-sidenav-7-3-2" role="button" aria-expanded="true" aria-controls="-sidenav-7-3-2"><span>Other command-line tools</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse show" id="-sidenav-7-3-2"><li class="nav-item"><a class="nav-link" href="/tools/build_runner"><div><span>build_runner</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/webdev"><div><span>webdev</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-7-4" role="button" aria-expanded="false" aria-controls="-sidenav-7-4"><span>Static analysis</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-7-4"><li class="nav-item"><a class="nav-link" href="/tools/analysis"><div><span>Customizing static analysis</span></div></a></li><li class="nav-item"><a class="nav-link" href="/deprecated/sound-problems"><div><span>Fixing common type problems</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/non-promotion-reasons"><div><span>Fixing type promotion failures</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/linter-rules"><div><span>Linter rules</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/diagnostic-messages"><div><span>Diagnostic messages</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-7-5" role="button" aria-expanded="false" aria-controls="-sidenav-7-5"><span>Testing & optimization</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-7-5"><li class="nav-item"><a class="nav-link" href="/tools/testing"><div><span>Testing</span></div></a></li><li class="nav-item"><a class="nav-link" href="/web/debugging"><div><span>Debugging web apps</span></div></a></li></ul></li></ul></li><li aria-hidden="true"><div class="sidenav-divider"></div></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-9" role="button" aria-expanded="false" aria-controls="-sidenav-9"><span>Resources</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-9"><li class="nav-item"><a class="nav-link" href="/resources/dart-cheatsheet"><div><span>Language cheatsheet</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/breaking-changes"><div><span>Breaking changes</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/language/evolution"><div><span>Language evolution</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/language/spec"><div><span>Language specification</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/dart-3-migration"><div><span>Dart 3 migration guide</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-9-6" role="button" aria-expanded="false" aria-controls="-sidenav-9-6"><span>Coming from ...</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-9-6"><li class="nav-item"><a class="nav-link" href="/resources/coming-from/js-to-dart"><div><span>JavaScript to Dart</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/coming-from/swift-to-dart"><div><span>Swift to Dart</span></div></a></li></ul></li><div class="sidenav-divider"></div><li class="nav-item"><a class="nav-link" href="/resources/faq"><div><span>FAQ</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/glossary"><div><span>Glossary</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/books"><div><span>Books</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/videos"><div><span>Videos</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tutorials"><div><span>Tutorials</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible" data-toggle="collapse" data-target="#-sidenav-10" role="button" aria-expanded="true" aria-controls="-sidenav-10"><span>Related sites</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse show" id="-sidenav-10"><li class="nav-item"><a class="nav-link" href="https://api.dart.dev" target="_blank" rel="noopener"><div><span>API reference</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://medium.com/dartlang" target="_blank" rel="noopener"><div><span>Blog</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://dartpad.dev" target="_blank" rel="noopener"><div><span>DartPad (online editor)</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://flutter.dev" target="_blank" rel="noopener"><div><span>Flutter</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev" target="_blank" rel="noopener"><div><span>Package site</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li></ul></div><main id="page-content"><div id="site-toc--side" class="site-toc"><header class="site-toc__title">Contents</header><ul class="section-nav"><li class="toc-entry nav-item"><a class="nav-link" href="#event-loop">Event Loop</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#asynchronous-programming">Asynchronous programming</a><ul class="nav"><li class="toc-entry nav-item"><a class="nav-link" href="#futures">Futures</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#the-async-await-syntax">The async-await syntax</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#streams">Streams</a></li></ul></li><li class="toc-entry nav-item"><a class="nav-link" href="#isolates">Isolates</a><ul class="nav"><li class="toc-entry nav-item"><a class="nav-link" href="#the-main-isolate">The main isolate</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#the-isolate-life-cycle">The isolate life cycle</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#event-handling">Event handling</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#background-workers">Background workers</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#using-isolates">Using isolates</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#performance-and-isolate-groups">Performance and isolate groups</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#limitations-of-isolates">Limitations of isolates</a></li></ul></li><li class="toc-entry nav-item"><a class="nav-link" href="#concurrency-on-the-web">Concurrency on the web</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#additional-resources">Additional resources</a></li></ul></div><article><div class="content"><div id="site-content-title"><h1>Concurrency in Dart</h1></div><div id="site-toc--inline" class="site-toc toc-collapsible toc-collapsed"><header class="site-toc__title">Contents <span class="site-toc--inline__toggle toc-toggle-down"><i class="material-symbols">keyboard_arrow_down</i></span> <span class="site-toc--inline__toggle toc-toggle-up"><i class="material-symbols">keyboard_arrow_up</i></span></header><ul class="section-nav"><li class="toc-entry"><a href="#event-loop">Event Loop</a></li><li class="toc-entry"><a href="#asynchronous-programming">Asynchronous programming</a><ul><li class="toc-entry"><a href="#futures">Futures</a></li><li class="toc-entry"><a href="#the-async-await-syntax">The async-await syntax</a></li><li class="toc-entry"><a href="#streams">Streams</a></li></ul></li><li class="toc-entry"><a href="#isolates">Isolates</a><ul><li class="toc-entry"><a href="#the-main-isolate">The main isolate</a></li><li class="toc-entry"><a href="#the-isolate-life-cycle">The isolate life cycle</a></li><li class="toc-entry"><a href="#event-handling">Event handling</a></li><li class="toc-entry"><a href="#background-workers">Background workers</a></li><li class="toc-entry"><a href="#using-isolates">Using isolates</a></li><li class="toc-entry"><a href="#performance-and-isolate-groups">Performance and isolate groups</a></li><li class="toc-entry"><a href="#limitations-of-isolates">Limitations of isolates</a></li></ul></li><li class="toc-entry"><a href="#concurrency-on-the-web">Concurrency on the web</a></li><li class="toc-entry"><a href="#additional-resources">Additional resources</a></li></ul><span class="site-toc--inline__toggle toc-toggle-more-items"><i class="material-symbols">more_horiz</i></span></div> <?code-excerpt path-base="concurrency"?> <style>article img { padding: 15px 0; }</style><p>This page contains a conceptual overview of how concurrent programming works in Dart. It explains the event-loop, async language features, and isolates from a high-level. For more practical code examples of using concurrency in Dart, read the <a href="/language/async">Asynchrony support</a> page and <a href="/language/isolates">Isolates</a> page.</p><p>Concurrent programming in Dart refers to both asynchronous APIs, like <code>Future</code> and <code>Stream</code>, and <em>isolates</em>, which allow you to move processes to separate cores.</p><p>All Dart code runs in isolates, starting in the default main isolate, and optionally expanding to whatever subsequent isolates you explicitly create. When you spawn a new isolate, it has its own isolated memory, and its own event loop. The event loop is what makes asynchronous and concurrent programming possible in Dart.</p><div class="header-wrapper"><h2 id="event-loop">Event Loop</h2><a class="heading-link" href="#event-loop" aria-label="Link to 'Event Loop' section">#</a></div><p>Dart’s runtime model is based on an event loop. The event loop is responsible for executing your program's code, collecting and processing events, and more.</p><p>As your application runs, all events are added to a queue, called the <em>event queue</em>. Events can be anything from requests to repaint the UI, to user taps and keystrokes, to I/O from the disk. Because your app can’t predict what order events will happen, the event loop processes events in the order they're queued, one at a time.</p><p><img src="/assets/img/language/concurrency/event-loop.png" alt="A figure showing events being fed, one by one, into the event loop"></p><p>The way the event loop functions resembles this code:</p><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">while</span><span style="color:#222222"> (eventQueue.</span><span style="color:#6200EE">waitForEvent</span><span style="color:#222222">()) {</span></span> <span class="line"><span style="color:#222222"> eventQueue.</span><span style="color:#6200EE">processNextEvent</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>This example event loop is synchronous and runs on a single thread. However, most Dart applications need to do more than one thing at a time. For example, a client application might need to execute an HTTP request, while also listening for a user to tap a button. To handle this, Dart offers many async APIs, like <a href="/language/async">Futures, Streams, and async-await</a>. These APIs are built around this event loop.</p><p>For example, consider making a network request:</p><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#222222">http.</span><span style="color:#6200EE">get</span><span style="color:#222222">(</span><span style="color:#11796D">'https://example.com'</span><span style="color:#222222">).</span><span style="color:#6200EE">then</span><span style="color:#222222">((response) {</span></span> <span class="line"><span style="color:#D43324"> if</span><span style="color:#222222"> (response.statusCode == </span><span style="color:#11796D">200</span><span style="color:#222222">) {</span></span> <span class="line"><span style="color:#6200EE"> print</span><span style="color:#222222">(</span><span style="color:#11796D">'Success!'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#222222"> } </span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>When this code reaches the event loop, it immediately calls the first clause, <code>http.get</code>, and returns a <code>Future</code>. It also tells the event loop to hold onto the callback in the <code>then()</code> clause until the HTTP request resolves. When that happens, it should execute that callback, passing the result of the request as an argument.</p><p><img src="/assets/img/language/concurrency/async-event-loop.png" alt="Figure showing async events being added to an event loop and holding onto a callback to execute later ."></p><p>This same model is generally how the event loop handles all other asynchronous events in Dart, such as <a href="https://api.dart.dev/dart-async/Stream-class.html"><code>Stream</code></a> objects.</p><div class="header-wrapper"><h2 id="asynchronous-programming">Asynchronous programming</h2><a class="heading-link" href="#asynchronous-programming" aria-label="Link to 'Asynchronous programming' section">#</a></div><p>This section summarizes the different types and syntaxes of asynchronous programming in Dart. If you're already familiar with <code>Future</code>, <code>Stream</code>, and async-await, then you can skip ahead to the <a href="#isolates">isolates section</a>.</p><div class="header-wrapper"><h3 id="futures">Futures</h3><a class="heading-link" href="#futures" aria-label="Link to 'Futures' section">#</a></div><p>A <code>Future</code> represents the result of an asynchronous operation that will eventually complete with a value or an error.</p><p>In this sample code, the return type of <code>Future&lt;String&gt;</code> represents a promise to eventually provide a <code>String</code> value (or error).</p> <?code-excerpt "lib/future_syntax.dart (read-async)"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">Future</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">String</span><span style="color:#222222">> </span><span style="color:#6200EE">_readFileAsync</span><span style="color:#222222">(</span><span style="color:#0468D7">String</span><span style="color:#222222"> filename) {</span></span> <span class="line"><span style="color:#D43324"> final</span><span style="color:#222222"> file = </span><span style="color:#0468D7">File</span><span style="color:#222222">(filename);</span></span> <span class="line"></span> <span class="line"><span style="color:#6E6E70"> // .readAsString() returns a Future.</span></span> <span class="line"><span style="color:#6E6E70"> // .then() registers a callback to be executed when `readAsString` resolves.</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#222222"> file.</span><span style="color:#6200EE">readAsString</span><span style="color:#222222">().</span><span style="color:#6200EE">then</span><span style="color:#222222">((contents) {</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#222222"> contents.</span><span style="color:#6200EE">trim</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#222222"> });</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h3 id="the-async-await-syntax">The async-await syntax</h3><a class="heading-link" href="#the-async-await-syntax" aria-label="Link to 'The async-await syntax' section">#</a></div><p>The <code>async</code> and <code>await</code> keywords provide a declarative way to define asynchronous functions and use their results.</p><p>Here's an example of some synchronous code that blocks while waiting for file I/O:</p> <?code-excerpt "lib/sync_number_of_keys.dart (blocking)"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">const</span><span style="color:#0468D7"> String</span><span style="color:#222222"> filename = </span><span style="color:#11796D">'with_keys.json'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6E6E70"> // Read some data.</span></span> <span class="line"><span style="color:#D43324"> final</span><span style="color:#222222"> fileData = </span><span style="color:#6200EE">_readFileSync</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#D43324"> final</span><span style="color:#222222"> jsonData = </span><span style="color:#6200EE">jsonDecode</span><span style="color:#222222">(fileData);</span></span> <span class="line"></span> <span class="line"><span style="color:#6E6E70"> // Use that data.</span></span> <span class="line"><span style="color:#6200EE"> print</span><span style="color:#222222">(</span><span style="color:#11796D">'Number of JSON keys: </span><span style="color:#11796D">${</span><span style="color:#222222">jsonData</span><span style="color:#11796D">.</span><span style="color:#222222">length</span><span style="color:#11796D">}</span><span style="color:#11796D">'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#222222">}</span></span> <span class="line"></span> <span class="line"><span style="color:#0468D7">String</span><span style="color:#6200EE"> _readFileSync</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#D43324"> final</span><span style="color:#222222"> file = </span><span style="color:#0468D7">File</span><span style="color:#222222">(filename);</span></span> <span class="line"><span style="color:#D43324"> final</span><span style="color:#222222"> contents = file.</span><span style="color:#6200EE">readAsStringSync</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#222222"> contents.</span><span style="color:#6200EE">trim</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>Here's similar code, but with changes (highlighted) to make it asynchronous:</p> <?code-excerpt "lib/async_number_of_keys.dart (non-blocking)" replace="/async|await|readAsString\(\)/[!$&!]/g; /Future<\w+\W/[!$&!]/g;"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">const</span><span style="color:#0468D7"> String</span><span style="color:#222222"> filename = </span><span style="color:#11796D">'with_keys.json'</span><span style="color:#222222">;</span></span> <span class="line"></span> <span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() </span><mark class="highlight"><span style="color:#D43324">async</span></mark><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#6E6E70"> // Read some data.</span></span> <span class="line"><span style="color:#D43324"> final</span><span style="color:#222222"> fileData = </span><mark class="highlight"><span style="color:#D43324">await</span></mark><span style="color:#6200EE"> _readFileAsync</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#D43324"> final</span><span style="color:#222222"> jsonData = </span><span style="color:#6200EE">jsonDecode</span><span style="color:#222222">(fileData);</span></span> <span class="line"></span> <span class="line"><span style="color:#6E6E70"> // Use that data.</span></span> <span class="line"><span style="color:#6200EE"> print</span><span style="color:#222222">(</span><span style="color:#11796D">'Number of JSON keys: </span><span style="color:#11796D">${</span><span style="color:#222222">jsonData</span><span style="color:#11796D">.</span><span style="color:#222222">length</span><span style="color:#11796D">}</span><span style="color:#11796D">'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#222222">}</span></span> <span class="line"></span> <span class="line"><mark class="highlight"><span style="color:#0468D7">Future</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">String</span><span style="color:#222222">></span></mark><span style="color:#222222"> </span><span style="color:#6200EE">_readFileAsync</span><span style="color:#222222">() </span><mark class="highlight"><span style="color:#D43324">async</span></mark><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#D43324"> final</span><span style="color:#222222"> file = </span><span style="color:#0468D7">File</span><span style="color:#222222">(filename);</span></span> <span class="line"><span style="color:#D43324"> final</span><span style="color:#222222"> contents = </span><mark class="highlight"><span style="color:#D43324">await</span></mark><span style="color:#222222"> file.</span><mark class="highlight"><span style="color:#6200EE">readAsString</span><span style="color:#222222">()</span></mark><span style="color:#222222">;</span></span> <span class="line"><span style="color:#D43324"> return</span><span style="color:#222222"> contents.</span><span style="color:#6200EE">trim</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>The <code>main()</code> function uses the <code>await</code> keyword in front of <code>_readFileAsync()</code> to let other Dart code (such as event handlers) use the CPU while native code (file I/O) executes. Using <code>await</code> also has the effect of converting the <code>Future&lt;String&gt;</code> returned by <code>_readFileAsync()</code> into a <code>String</code>. As a result, the <code>contents</code> variable has the implicit type <code>String</code>.</p><aside class="alert alert-info"><div class="alert-header"><span class="material-symbols" aria-hidden="true">info</span> <span>Note</span></div><div class="alert-content"><p>The <code>await</code> keyword works only in functions that have <code>async</code> before the function body.</p></div></aside><p>As the following figure shows, the Dart code pauses while <code>readAsString()</code> executes non-Dart code, in either the Dart runtime or the operating system. Once <code>readAsString()</code> returns a value, Dart code execution resumes.</p><p><img src="/assets/img/language/concurrency/basics-await.png" alt="Flowchart-like figure showing app code executing from start to exit, waiting for native I/O in between"></p><div class="header-wrapper"><h3 id="streams">Streams</h3><a class="heading-link" href="#streams" aria-label="Link to 'Streams' section">#</a></div><p>Dart also supports asynchronous code in the form of streams. Streams provide values in the future and repeatedly over time. A promise to provide a series of <code>int</code> values over time has the type <code>Stream&lt;int&gt;</code>.</p><p>In the following example, the stream created with <code>Stream.periodic</code> repeatedly emits a new <code>int</code> value every second.</p> <?code-excerpt "lib/stream_syntax.dart"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">Stream</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">int</span><span style="color:#222222">> stream = </span><span style="color:#0468D7">Stream</span><span style="color:#222222">.</span><span style="color:#6200EE">periodic</span><span style="color:#222222">(</span><span style="color:#D43324">const</span><span style="color:#0468D7"> Duration</span><span style="color:#222222">(seconds: </span><span style="color:#11796D">1</span><span style="color:#222222">), (i) => i * i);</span></span></code></pre></div></div><div class="header-wrapper"><h4 id="await-for-and-yield">await-for and yield</h4><a class="heading-link" href="#await-for-and-yield" aria-label="Link to 'await-for and yield' section">#</a></div><p>Await-for is a type of for loop that executes each subsequent iteration of the loop as new values are provided. In other words, it’s used to “loop over” streams. In this example, a new value will be emitted from the function <code>sumStream</code> as new values are emitted from the stream that’s provided as an argument. The <code>yield</code> keyword is used rather than <code>return</code> in functions that return streams of values.</p> <?code-excerpt "lib/await_for_syntax.dart"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">Stream</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">int</span><span style="color:#222222">> </span><span style="color:#6200EE">sumStream</span><span style="color:#222222">(</span><span style="color:#0468D7">Stream</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">int</span><span style="color:#222222">> stream) </span><span style="color:#D43324">async</span><span style="color:#222222">* {</span></span> <span class="line"><span style="color:#D43324"> var</span><span style="color:#222222"> sum = </span><span style="color:#11796D">0</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#D43324"> await</span><span style="color:#D43324"> for</span><span style="color:#222222"> (</span><span style="color:#D43324">final</span><span style="color:#222222"> value </span><span style="color:#D43324">in</span><span style="color:#222222"> stream) {</span></span> <span class="line"><span style="color:#D43324"> yield</span><span style="color:#222222"> sum += value;</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>If you'd like to learn more about using <code>async</code>, <code>await</code>, <code>Stream</code>s and <code>Future</code>s, check out the <a href="/libraries/async/async-await">asynchronous programming tutorial</a>.</p><div class="header-wrapper"><h2 id="isolates">Isolates</h2><a class="heading-link" href="#isolates" aria-label="Link to 'Isolates' section">#</a></div><p>Dart supports concurrency via isolates, in addition to <a href="#asynchronous-programming">asynchronous APIs</a>. Most modern devices have multi-core CPUs. To take advantage of multiple cores, developers sometimes use shared-memory threads running concurrently. However, shared-state concurrency is <a href="https://en.wikipedia.org/wiki/Race_condition#In_software">error prone</a> and can lead to complicated code.</p><p>Instead of threads, all Dart code runs inside isolates. Using isolates, your Dart code can perform multiple independent tasks at once, using additional processor cores if they're available. Isolates are like threads or processes, but each isolate has its own memory and a single thread running an event loop.</p><p>Each isolate has its own global fields, ensuring that none of the state in an isolate is accessible from any other isolate. Isolates can only communicate to each other via message passing. No shared state between isolates means concurrency complexities like <a href="https://en.wikipedia.org/wiki/Lock_(computer_science)">mutexes or locks</a> and <a href="https://en.wikipedia.org/wiki/Race_condition#Data_race">data races</a> won't occur in Dart. That said, isolates don't prevent race conditions all together. For more information on this concurrency model, read about the <a href="https://en.wikipedia.org/wiki/Actor_model">Actor model</a>.</p><aside class="alert alert-info"><div class="alert-header"><span class="material-symbols" aria-hidden="true">info</span> <span>Platform note</span></div><div class="alert-content"><p>Only the <a href="/overview#platform">Dart Native platform</a> implements isolates. To learn more about the Dart Web platform, see the <a href="#concurrency-on-the-web">Concurrency on the web</a> section.</p></div></aside><div class="header-wrapper"><h3 id="the-main-isolate">The main isolate</h3><a class="heading-link" href="#the-main-isolate" aria-label="Link to 'The main isolate' section">#</a></div><p>In most cases, you don't need to think about isolates at all. Dart programs run in the main isolate by default. It’s the thread where a program starts to run and execute, as shown in the following figure:</p><p><img src="/assets/img/language/concurrency/basics-main-isolate.png" alt="A figure showing a main isolate, which runs , responds to events, and then exits"></p><p>Even single-isolate programs can execute smoothly. Before continuing to the next line of code, these apps use <a href="/libraries/async/async-await">async-await</a> to wait for asynchronous operations to complete. A well-behaved app starts quickly, getting to the event loop as soon as possible. The app then responds to each queued event promptly, using asynchronous operations as necessary.</p><div class="header-wrapper"><h3 id="the-isolate-life-cycle">The isolate life cycle</h3><a class="heading-link" href="#the-isolate-life-cycle" aria-label="Link to 'The isolate life cycle' section">#</a></div><p>As the following figure shows, every isolate starts by running some Dart code, such as the <code>main()</code> function. This Dart code might register some event listeners—to respond to user input or file I/O, for example. When the isolate's initial function returns, the isolate stays around if it needs to handle events. After handling the events, the isolate exits.</p><p><img src="/assets/img/language/concurrency/basics-isolate.png" alt="A more general figure showing that any isolate runs some code, optionally responds to events, and then exits"></p><div class="header-wrapper"><h3 id="event-handling">Event handling</h3><a class="heading-link" href="#event-handling" aria-label="Link to 'Event handling' section">#</a></div><p>In a client app, the main isolate's event queue might contain repaint requests and notifications of tap and other UI events. For example, the following figure shows a repaint event, followed by a tap event, followed by two repaint events. The event loop takes events from the queue in first in, first out order.</p><p><img src="/assets/img/language/concurrency/event-loop.png" alt="A figure showing events being fed, one by one, into the event loop"></p><p>Event handling happens on the main isolate after <code>main()</code> exits. In the following figure, after <code>main()</code> exits, the main isolate handles the first repaint event. After that, the main isolate handles the tap event, followed by a repaint event.</p><p>If a synchronous operation takes too much processing time, the app can become unresponsive. In the following figure, the tap-handling code takes too long, so subsequent events are handled too late. The app might appear to freeze, and any animation it performs might be jerky.</p><p><img src="/assets/img/language/concurrency/event-jank.png" alt="A figure showing a tap handler with a too-long execution time"></p><p>In client apps, the result of a too-lengthy synchronous operation is often <a href="https://docs.flutter.dev/perf/rendering-performance">janky (non-smooth) UI animation</a>. Worse, the UI might become completely unresponsive.</p><div class="header-wrapper"><h3 id="background-workers">Background workers</h3><a class="heading-link" href="#background-workers" aria-label="Link to 'Background workers' section">#</a></div><p>If your app's UI becomes unresponsive due to a time-consuming computation—<a href="https://docs.flutter.dev/cookbook/networking/background-parsing">parsing a large JSON file</a>, for example—consider offloading that computation to a worker isolate, often called a <em>background worker.</em> A common case, shown in the following figure, is spawning a simple worker isolate that performs a computation and then exits. The worker isolate returns its result in a message when it exits.</p><p><img src="/assets/img/language/concurrency/isolate-bg-worker.png" alt="A figure showing a main isolate and a simple worker isolate"></p><p>A worker isolate can perform I/O (reading and writing files, for example), set timers, and more. It has its own memory and doesn't share any state with the main isolate. The worker isolate can block without affecting other isolates.</p><div class="header-wrapper"><h3 id="using-isolates">Using isolates</h3><a class="heading-link" href="#using-isolates" aria-label="Link to 'Using isolates' section">#</a></div><p>There are two ways to work with isolates in Dart, depending on the use-case:</p><ul><li>Use <a href="https://api.dart.dev/dart-isolate/Isolate/run.html"><code>Isolate.run()</code></a> to perform a single computation on a separate thread.</li><li>Use <a href="https://api.dart.dev/dart-isolate/Isolate/spawn.html"><code>Isolate.spawn()</code></a> to create an isolate that will handle multiple messages over time, or a background worker. For more information on working with long-lived isolates, read the <a href="/language/isolates">Isolates</a> page.</li></ul><p>In most cases, <code>Isolate.run</code> is the recommended API to run processes in the background.</p><div class="header-wrapper"><h4 id="isolate-run"><code>Isolate.run()</code></h4><a class="heading-link" href="#isolate-run" aria-label="Link to 'Isolate.run()' section">#</a></div><p>The static <code>Isolate.run()</code> method requires one argument: a callback that will be run on the newly spawned isolate.</p> <?code-excerpt "lib/isolate_run_syntax.dart (slow)"?> <div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">int</span><span style="color:#6200EE"> slowFib</span><span style="color:#222222">(</span><span style="color:#0468D7">int</span><span style="color:#222222"> n) => n &#x3C;= </span><span style="color:#11796D">1</span><span style="color:#222222"> ? </span><span style="color:#11796D">1</span><span style="color:#222222"> : </span><span style="color:#6200EE">slowFib</span><span style="color:#222222">(n - </span><span style="color:#11796D">1</span><span style="color:#222222">) + </span><span style="color:#6200EE">slowFib</span><span style="color:#222222">(n - </span><span style="color:#11796D">2</span><span style="color:#222222">);</span></span> <span class="line"></span> <span class="line"><span style="color:#6E6E70">// Compute without blocking current isolate.</span></span> <span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> fib40</span><span style="color:#222222">() </span><span style="color:#D43324">async</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#D43324"> var</span><span style="color:#222222"> result = </span><span style="color:#D43324">await</span><span style="color:#0468D7"> Isolate</span><span style="color:#222222">.</span><span style="color:#6200EE">run</span><span style="color:#222222">(() => </span><span style="color:#6200EE">slowFib</span><span style="color:#222222">(</span><span style="color:#11796D">40</span><span style="color:#222222">));</span></span> <span class="line"><span style="color:#6200EE"> print</span><span style="color:#222222">(</span><span style="color:#11796D">'Fib(40) = </span><span style="color:#11796D">$</span><span style="color:#222222">result</span><span style="color:#11796D">'</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h3 id="performance-and-isolate-groups">Performance and isolate groups</h3><a class="heading-link" href="#performance-and-isolate-groups" aria-label="Link to 'Performance and isolate groups' section">#</a></div><p>When an isolate calls <a href="https://api.dart.dev/dart-isolate/Isolate/spawn.html"><code>Isolate.spawn()</code></a>, the two isolates have the same executable code and are in the same <em>isolate group</em>. Isolate groups enable performance optimizations such as sharing code; a new isolate immediately runs the code owned by the isolate group. Also, <code>Isolate.exit()</code> works only when the isolates are in the same isolate group.</p><p>In some special cases, you might need to use <a href="https://api.dart.dev/dart-isolate/Isolate/spawnUri.html"><code>Isolate.spawnUri()</code></a>, which sets up the new isolate with a copy of the code that's at the specified URI. However, <code>spawnUri()</code> is much slower than <code>spawn()</code>, and the new isolate isn't in its spawner's isolate group. Another performance consequence is that message passing is slower when isolates are in different groups.</p><div class="header-wrapper"><h3 id="limitations-of-isolates">Limitations of isolates</h3><a class="heading-link" href="#limitations-of-isolates" aria-label="Link to 'Limitations of isolates' section">#</a></div><div class="header-wrapper"><h4 id="isolates-arent-threads">Isolates aren't threads</h4><a class="heading-link" href="#isolates-arent-threads" aria-label="Link to 'Isolates aren't threads' section">#</a></div><p>If you’re coming to Dart from a language with multithreading, it’d be reasonable to expect isolates to behave like threads, but that isn’t the case. Each isolate has its own state, ensuring that none of the state in an isolate is accessible from any other isolate. Therefore, isolates are limited by their access to their own memory.</p><p>For example, if you have an application with a global mutable variable, that variable will be a separate variable in your spawned isolate. If you mutate that variable in the spawned isolate, it will remain untouched in the main isolate. This is how isolates are meant to function, and it's important to keep in mind when you’re considering using isolates.</p><div class="header-wrapper"><h4 id="message-types">Message types</h4><a class="heading-link" href="#message-types" aria-label="Link to 'Message types' section">#</a></div><p>Messages sent via <a href="https://api.dart.dev/dart-isolate/SendPort-class.html"><code>SendPort</code></a> can be almost any type of Dart object, but there are a few exceptions:</p><ul><li>Objects with native resources, such as <a href="https://api.dart.dev/dart-io/Socket-class.html"><code>Socket</code></a>.</li><li><a href="https://api.dart.dev/dart-isolate/ReceivePort-class.html"><code>ReceivePort</code></a></li><li><a href="https://api.dart.dev/dart-ffi/DynamicLibrary-class.html"><code>DynamicLibrary</code></a></li><li><a href="https://api.dart.dev/dart-ffi/Finalizable-class.html"><code>Finalizable</code></a></li><li><a href="https://api.dart.dev/dart-core/Finalizer-class.html"><code>Finalizer</code></a></li><li><a href="https://api.dart.dev/dart-ffi/NativeFinalizer-class.html"><code>NativeFinalizer</code></a></li><li><a href="https://api.dart.dev/dart-ffi/Pointer-class.html"><code>Pointer</code></a></li><li><a href="https://api.dart.dev/dart-developer/UserTag-class.html"><code>UserTag</code></a></li><li>Instances of classes that are marked with <code>@pragma('vm:isolate-unsendable')</code></li></ul><p>Apart from those exceptions, any object can be sent. Check out the <a href="https://api.dart.dev/dart-isolate/SendPort/send.html"><code>SendPort.send</code></a> documentation for more information.</p><p>Note that <code>Isolate.spawn()</code> and <code>Isolate.exit()</code> abstract over <code>SendPort</code> objects, so they're subject to the same limitations.</p><div class="header-wrapper"><h4 id="synchronous-blocking-communication-between-isolates">Synchronous blocking communication between isolates</h4><a class="heading-link" href="#synchronous-blocking-communication-between-isolates" aria-label="Link to 'Synchronous blocking communication between isolates' section">#</a></div><p>There is a limit to the number of isolates that can run in parallel. This limit doesn't affect the standard <em>asynchronous</em> communication between isolates via messages in Dart. You can have hundreds of isolates running concurrently and making progress. The isolates are scheduled on the CPU in round-robin fashion, and yield to each other often.</p><p>Isolates can only communicate <em>synchronously</em> outside of pure Dart, using C code via <a href="/interop/c-interop">FFI</a> to do so. Attempting synchronous communication between isolates by synchronous blocking in FFI calls may result in deadlock if the number of isolates is over the limit, unless special care is taken. The limit is not hardcoded to a particular number, it's calculated based on the Dart VM heap size available to the Dart application.</p><p>To avoid this situation, the C code performing synchronous blocking needs to leave the current isolate before performing the blocking operation and re-enter it before returning to Dart from the FFI call. Read about <a href="https://github.com/dart-lang/sdk/blob/c9a8bbd8d6024e419b5e5f26b5131285eb19cc93/runtime/include/dart_api.h#L1254"><code>Dart_EnterIsolate</code></a> and <a href="https://github.com/dart-lang/sdk/blob/c9a8bbd8d6024e419b5e5f26b5131285eb19cc93/runtime/include/dart_api.h#L1455"><code>Dart_ExitIsolate</code></a> to learn more.</p><p><a id="web"></a></p><div class="header-wrapper"><h2 id="concurrency-on-the-web">Concurrency on the web</h2><a class="heading-link" href="#concurrency-on-the-web" aria-label="Link to 'Concurrency on the web' section">#</a></div><p>All Dart apps can use <code>async-await</code>, <code>Future</code>, and <code>Stream</code> for non-blocking, interleaved computations. The <a href="/overview#platform">Dart web platform</a>, however, does not support isolates. Dart web apps can use <a href="https://developer.mozilla.org/docs/Web/API/Web_Workers_API/Using_web_workers">web workers</a> to run scripts in background threads similar to isolates. Web workers' functionality and capabilities differ somewhat from isolates, though.</p><p>For instance, when web workers send data between threads, they copy the data back and forth. Data copying can be very slow, though, especially for large messages. Isolates do the same, but also provide APIs that can more efficiently <em>transfer</em> the memory that holds the message instead.</p><p>Creating web workers and isolates also differs. You can only create web workers by declaring a separate program entrypoint and compiling it separately. Starting a web worker is similar to using <code>Isolate.spawnUri</code> to start an isolate. You can also start an isolate with <code>Isolate.spawn</code>, which requires fewer resources because it <a href="#performance-and-isolate-groups">reuses some of the same code and data</a> as the spawning isolate. Web workers don't have an equivalent API.</p><div class="header-wrapper"><h2 id="additional-resources">Additional resources</h2><a class="heading-link" href="#additional-resources" aria-label="Link to 'Additional resources' section">#</a></div><ul><li>If you’re using many isolates, consider the <a href="https://api.flutter.dev/flutter/dart-ui/IsolateNameServer-class.html"><code>IsolateNameServer</code></a> in Flutter, or <a href="https://pub.dev/packages/isolate_name_server"><code>package:isolate_name_server</code></a> that provides similar functionality for non-Flutter Dart applications.</li><li>Read more about <a href="https://en.wikipedia.org/wiki/Actor_model">Actor model</a>, which Dart's isolates are based on.</li><li>Additional documentation on <code>Isolate</code> APIs:<ul><li><a href="https://api.dart.dev/dart-isolate/Isolate/exit.html"><code>Isolate.exit()</code></a></li><li><a href="https://api.dart.dev/dart-isolate/Isolate/spawn.html"><code>Isolate.spawn()</code></a></li><li><a href="https://api.dart.dev/dart-isolate/ReceivePort-class.html"><code>ReceivePort</code></a></li><li><a href="https://api.dart.dev/dart-isolate/SendPort-class.html"><code>SendPort</code></a></li></ul></li></ul><nav id="subnav"><ul><li class="previous"><a href="/language/modifier-reference">&lang;&nbsp;&nbsp;Class modifiers reference</a></li><li class="next"><a href="/language/async">Async&nbsp;&nbsp;&rang;</a></li></ul></nav><p id="page-github-links"><span>Unless stated otherwise, the documentation on this site reflects Dart 3.7.0. Page last updated on 2024-11-17.</span> <a href="https://github.com/dart-lang/site-www/tree/main/src/content/language/concurrency.md" target="_blank" rel="noopener">View source</a> <span>or </span><a href="https://github.com/dart-lang/site-www/issues/new?template=1_page_issue.yml&page-url=https://dart.dev/language/concurrency/&page-source=https://github.com/dart-lang/site-www/tree/main/src/content/language/concurrency.md" title="Report an issue with this page" target="_blank" rel="noopener">report an issue</a>.</p></div></article></main></div><footer id="page-footer"><div class="footer-section footer-main"><a href="/" class="brand" title="Dart"><img src="/assets/img/logo/logo-white-text.svg" alt="Dart" width="164"></a><div class="footer-social-links"><a href="https://medium.com/dartlang" target="_blank" rel="noopener" title="Dart's Medium publication"><svg><use href="/assets/img/social/medium.svg#medium"></use></svg> </a><a href="https://github.com/dart-lang" target="_blank" rel="noopener" title="Dart's GitHub organization"><svg><use href="/assets/img/social/github.svg#github"></use></svg> </a><a href="https://bsky.app/profile/dart.dev" target="_blank" rel="noopener" title="Dart's Bluesky profile"><svg><use href="/assets/img/social/bluesky.svg#bluesky"></use></svg> </a><a href="https://twitter.com/dart_lang" target="_blank" rel="noopener" title="Dart's X (Twitter) profile"><svg><use href="/assets/img/social/x.svg#x"></use></svg></a></div></div><div class="footer-section footer-tray"><div class="footer-licenses">Except as otherwise noted, this site is licensed under a <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>, and code samples are licensed under the <a href="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</a>.</div><div class="footer-utility-links"><ul><li><a href="/terms" title="Terms of use">Terms</a></li><li><a href="https://policies.google.com/privacy" target="_blank" rel="noopener" title="Privacy policy">Privacy</a></li><li><a href="/security" title="Security philosophy and practices">Security</a></li></ul></div></div></footer></div></body></html>

Pages: 1 2 3 4 5 6 7 8 9 10