{"id":497318,"date":"2026-10-05T07:08:46","date_gmt":"2026-10-05T07:08:46","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=497318"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2026-10-05T07:08:46","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=497318","title":{"rendered":"Kotlin Coroutines \u2014 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u0441 \u0434\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u0440\u0430\u043c\u0438 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u043e\u0448\u0438\u0431\u043e\u043a"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/bf4\/e42\/636\/bf4e426365cd7172d52dcf628fcceddc.png\" width=\"630\" height=\"574\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/bf4\/e42\/636\/bf4e426365cd7172d52dcf628fcceddc.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/bf4\/e42\/636\/bf4e426365cd7172d52dcf628fcceddc.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0420\u0430\u043d\u0435\u0435 \u043c\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c c <a href=\"https:\/\/habr.com\/ru\/articles\/1053868\/\" rel=\"noopener nofollow\">\u043f\u0440\u043e\u0431\u0435\u043c\u0430\u0442\u0438\u043a\u043e\u0439<\/a>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u0432\u0435\u043b\u0430 \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430 Kotlin Coroutines \u0430 \u0442\u0430\u043a \u0436\u0435 \u0441 \u0442\u0435\u043c\u0438 <a href=\"https:\/\/habr.com\/ru\/article\/edit\/1067510\/\" rel=\"noopener nofollow\">\u0438\u0434\u0435\u044f\u043c\u0438<\/a>, \u0447\u0442\u043e \u0431\u044b\u043b\u0438 \u0437\u0430\u043b\u043e\u0436\u0435\u043d\u044b \u043f\u0440\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. <\/p>\n<figure class=\"full-width \"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a87\/dc7\/ae1\/a87dc7ae1e450e52794f3f5829ee302f.png\" width=\"1125\" height=\"468\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/a87\/dc7\/ae1\/a87dc7ae1e450e52794f3f5829ee302f.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a87\/dc7\/ae1\/a87dc7ae1e450e52794f3f5829ee302f.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<h2>\u0414\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u0440\u044b<\/h2>\n<p>C\u043c\u044b\u0441\u043b \u0434\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u0440\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 &#8212; \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043d\u0430 \u043a\u0430\u043a\u043e\u043c-\u0442\u043e \u043f\u043e\u0442\u043e\u043a\u0435. \u0414\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u0440 &#8212; \u044d\u0442\u043e \u0438 \u0435\u0441\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043f\u0443\u043b \u043f\u043e\u0442\u043e\u043a\u043e\u0432.<\/p>\n<p>\u041a\u0430\u043a \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0438\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043a\u043e\u0440\u0443\u0442\u0438\u043d, \u043e\u0431\u044a\u0435\u043a\u0442 \u043a \u0434\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u0440\u0443 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u0438\u0437 <a href=\"https:\/\/habr.com\/ru\/article\/edit\/1067510\/\" rel=\"noopener nofollow\">\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b<\/a>.<\/p>\n<pre><code class=\"kotlin\">val currentDispatcher = coroutineContext[ContinuationInterceptor] as CoroutineDispatcher<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper\"><\/span><\/a><\/div><\/pre>\n<p>\u0423\u043a\u0430\u0437\u0430\u0442\u044c \u0434\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u0440, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430 \u043c\u043e\u0436\u043d\u043e \u044f\u0432\u043d\u043e \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u0438\u043b\u0438 \u043f\u0440\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0438 suspend-\u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<pre><code class=\"kotlin\">launc (dispatcher) {   ... }suspend fun helloWorld() = withContext(dispatcher) {  ....}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0434\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u0440 \u044f\u0432\u043d\u043e \u043d\u0435 \u0437\u0430\u0434\u0430\u0435\u0442\u0441\u044f &#8212; \u0434\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0439 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b.<\/p>\n<p>\u0418\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 coroutine runtime \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 <a href=\"https:\/\/habr.com\/ru\/companies\/otus\/articles\/854090\/?ysclid=mtl6d5np1p753192883\" rel=\"noopener nofollow\">\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0434\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u0440\u044b<\/a>:<\/p>\n<p><strong>Dispatchers.Default <\/strong><\/p>\n<ul>\n<li>\n<p>\u041f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439, \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0445 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043d\u0430 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 (CPU).\u00a0<\/p>\n<\/li>\n<li>\n<p>\u0420\u0430\u0437\u043c\u0435\u0440 \u043f\u0443\u043b\u0430 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u044f\u0434\u0435\u0440 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435.\u00a0<\/p>\n<\/li>\n<\/ul>\n<p><strong>Dispatchers.Main<\/strong><\/p>\n<ul>\n<li>\n<p>\u0414\u043b\u044f Android \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 (UI thread).\u00a0<\/p>\n<\/li>\n<li>\n<p>\u0412\u0430\u0436\u043d\u043e \u0438\u0437\u0431\u0435\u0433\u0430\u0442\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430.\u00a0<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u0430\u0445 (\u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 Main-\u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440).<\/p>\n<\/li>\n<\/ul>\n<p><strong>Dispatchers.IO<\/strong><\/p>\n<ul>\n<li>\n<p>\u041f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 (\u0432\u0432\u043e\u0434\u0430-\u0432\u044b\u0432\u043e\u0434\u0430, \u0447\u0442\u0435\u043d\u0438\u0435\/\u0437\u0430\u043f\u0438\u0441\u044c \u0444\u0430\u0439\u043b\u043e\u0432, \u0434\u043e\u0441\u0442\u0443\u043f \u043a Shared Preferences \u0438 \u0442.\u0434.).\u00a0<\/p>\n<\/li>\n<li>\n<p>\u0420\u0430\u0437\u043c\u0435\u0440 \u043f\u0443\u043b\u0430 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 64 (\u0438\u043b\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0447\u0438\u0441\u043b\u0443 \u044f\u0434\u0435\u0440, \u0435\u0441\u043b\u0438 \u0438\u0445 \u0431\u043e\u043b\u044c\u0448\u0435 64).\u00a0<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0445 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438.\u00a0<\/p>\n<\/li>\n<\/ul>\n<p><strong>Dispatchers.Unconfined<\/strong><\/p>\n<ul>\n<li>\n<p>\u041a\u043e\u0440\u0443\u0442\u0438\u043d\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c \u0436\u0435 \u043f\u043e\u0442\u043e\u043a\u0435, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u044b\u043b\u0430 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430; \u0441\u043c\u0435\u043d\u0430 \u043f\u043e\u0442\u043e\u043a\u0430 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0442\u0438 \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u0437\u043e\u0432\u0430 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0439 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u0438\u0437 \u0434\u043e\u0447\u0435\u0440\u043d\u0435\u0439.\u00a0<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u0435\u0437\u0435\u043d \u0434\u043b\u044f \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u043e\u0432.\u00a0<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u0440 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e:<\/p>\n<pre><code class=\"kotlin\">val executor = Executors.newFixedThreadPool(2)val customDispatcher = executor.asCoroutineDispatcher()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u043e\u0434\u043d\u0430\u043a\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a \u043d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u043c \u0446\u0438\u043a\u043b\u043e\u043c \u0434\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u0440\u0430 \u0432 \u0440\u0443\u0447\u043d\u0443\u044e. <\/p>\n<p>\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u043c\u044b\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0431\u0430\u0437\u0435 <strong>Dispatchers.Default  <\/strong>\u0438\u043b\u0438<strong>  Dispatchers.IO <\/strong>\u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0443\u043b\u0430 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u044b\u0437\u043e\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430<strong> <\/strong><a href=\"https:\/\/kotlinlang.org\/api\/kotlinx.coroutines\/kotlinx-coroutines-core\/kotlinx.coroutines\/-coroutine-dispatcher\/limited-parallelism.html\" rel=\"noopener nofollow\"><em>limitedParallelism<\/em><\/a><\/p>\n<pre><code class=\"kotlin\">val confined = Dispatchers.Default.limitedParallelism(1, \"incrementDispatcher\")var counter = 0\/\/ Invoked from arbitrary coroutineslaunch(confined) {    \/\/ This increment is sequential and race-free    ++counter}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<h2>\u041d\u044e\u0430\u043d\u0441\u044b \u0440\u0430\u0431\u043e\u0442\u044b c \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430\u043c\u0438, \u043f\u0440\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0437\u0430\u0431\u044b\u0432\u0430\u0442\u044c<\/h2>\n<h3>ThreadLocal &#8212; \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435<\/h3>\n<p>\u0412\u044b\u0437\u043e\u0432 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b &#8212; \u044d\u0442\u043e \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f. \u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u0437\u043e\u0432\u0430 suspend-\u043c\u0435\u0442\u043e\u0434\u0430 \u043f\u043e\u0442\u043e\u043a, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0439 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0443 \u0432 \u043e\u0431\u0449\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f. <\/p>\n<pre><code class=\"kotlin\">suspend fun helloWorld()  {    val threadLocal = ThreadLocal&lt;String&gt;()    threadLocal.set(\"main\")    println(\"thread local value: '${threadLocal.get()}'\")    delay(2000)    \/\/ \u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043a\u0430\u043a \"main\", \u0442\u0430\u043a \u0438 null    println(\"thread local value: '${threadLocal.get()}'\")}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0432 \u043b\u043e\u0433\u0438\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432\u0441\u0435 \u0436\u0435 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 \u043f\u043e\u0442\u043e\u043a\u043e\u043c, \u0441\u0442\u043e\u0438\u0442 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435\u043c <a href=\"https:\/\/kotlinlang.org\/api\/kotlinx.coroutines\/kotlinx-coroutines-core\/kotlinx.coroutines\/as-context-element.html\" rel=\"noopener nofollow\"><em>asContextElement<\/em><\/a><em> <\/em>\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043a \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0443 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b:<\/p>\n<pre><code class=\"kotlin\"> suspend fun helloWorld() = withContext(Dispatchers.Default) {     val threadLocal = ThreadLocal&lt;String&gt;()     threadLocal.set(\"main\")     launch(threadLocal.asContextElement()) {         println(\"thread local value: '${threadLocal.get()}'\")         delay(2000)         println(\"thread local value: '${threadLocal.get()}'\")     } }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<h3>\u041f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b<\/h3>\n<p>\u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u043c\u0435\u0442\u043e\u0434\u0430  <a href=\"https:\/\/kotlinlang.org\/api\/kotlinx.coroutines\/kotlinx-coroutines-core\/kotlinx.coroutines\/cancel.html\" rel=\"noopener nofollow\"><em>job.cancel()<\/em><\/a>\u00a0 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u0434\u0432\u0435  \u0432\u0435\u0449\u0438:<\/p>\n<ol>\n<li>\n<p>\u0412\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0444\u043b\u0430\u0433 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f <a href=\"https:\/\/kotlinlang.org\/api\/kotlinx.coroutines\/kotlinx-coroutines-core\/kotlinx.coroutines\/-job\/\" rel=\"noopener nofollow\"><em>Job<\/em><\/a>\u00a0\u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0441\u0442\u0430\u0442\u0443\u0441 <em>Cancelling<\/em>.<\/p>\n<\/li>\n<li>\n<p><em>Job <\/em>\u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u0441\u043f\u0438\u0441\u043a\u0443 \u0441\u0432\u043e\u0438\u0445 \u0434\u0435\u0442\u0435\u0439 \u0438 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u00a0<em>cancel()<\/em>\u00a0\u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u043d\u0438\u0445.<\/p>\n<\/li>\n<\/ol>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0440\u0430\u0431\u043e\u0442\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 <em>cancel()<\/em>\u00a0\u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f. \u041c\u0435\u0442\u043e\u0434 \u043d\u0435 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u0434 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0438 \u0441\u0430\u043c \u043f\u043e \u0441\u0435\u0431\u0435 \u043d\u0435 \u0431\u0440\u043e\u0441\u0430\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0432 \u0442\u043e\u043c \u043c\u0435\u0441\u0442\u0435, \u0433\u0434\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430. <\/p>\n<p>\u0417\u0430 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u043a\u043e\u0440\u0443\u0442\u0438\u043d \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 kotlin runtime. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u0430\u043c\u0430 \u043e\u0442\u043c\u0435\u043d\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043d\u0435 \u0441\u0440\u0430\u0437\u0443, \u0430 \u0432 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0439 \u0442\u043e\u0447\u043a\u0435 \u0432\u044b\u0437\u043e\u0432\u0430 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b  (suspension point). \u0415\u0441\u043b\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u043e\u043b\u0433\u0430\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u043a\u043e\u0440\u0443\u0442\u0438\u043d &#8212; \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0434\u0432\u0438\u0441\u043d\u0443\u0442\u044c. \u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u0434\u043e\u043b\u0433\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043d\u0443\u0436\u043d\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0441\u0442\u0430\u0442\u0443\u0441 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u0447\u0435\u0440\u0435\u0437 \u0432\u044b\u0437\u043e\u0432 <a href=\"https:\/\/kotlinlang.org\/api\/kotlinx.coroutines\/kotlinx-coroutines-core\/kotlinx.coroutines\/ensure-active.html\" rel=\"noopener nofollow\">ensureActive()<\/a>. <\/p>\n<pre><code class=\"kotlin\">while (true) {    ensureActive()  \/\/ suspend-\u0444\u0443\u043d\u043a\u0446\u0438\u044f; \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0435 \u0431\u044b\u043b\u043e \u043b\u0438 \u043e\u0442\u043c\u0435\u043d\u044b \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b      heavyOperationPart() \/\/ \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<h3>CancellationException<\/h3>\n<p>\u0414\u043b\u044f \u0441\u0438\u0433\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0435, \u0442\u043e\u0433\u043e \u0447\u0442\u043e \u043e\u043d\u0430 \u0431\u044b\u043b\u0430 \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u0430 kotlin runtime \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 <a href=\"https:\/\/kotlinlang.org\/api\/kotlinx.coroutines\/kotlinx-coroutines-core\/kotlinx.coroutines\/-cancellation-exception\/\" rel=\"noopener nofollow\"><em>CancellationException<\/em><\/a>. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0432\u044b\u043b\u0435\u0442\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0447\u043a\u0438 \u0432\u044b\u0437\u043e\u0432\u0430 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b (suspension point). \u0415\u0441\u043b\u0438 \u0442\u0430\u043a\u043e\u0432\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u043d\u0435\u0442 &#8212; \u0442\u043e \u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e.<\/p>\n<p><em>CancellationException<\/em> &#8212; \u043e\u0431\u044b\u0447\u043d\u043e\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 \u0431\u043b\u043e\u043a\u0435 catch. \u041d\u043e <em>CancellationException<\/em> \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u0434\u0430\u043b\u044c\u0448\u0435. <\/p>\n<pre><code class=\"kotlin\">while (true) {    try {        ensureActive()  \/\/ suspend-\u0444\u0443\u043d\u043a\u0446\u0438\u044f; \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0435 \u0431\u044b\u043b\u043e \u043b\u0438 \u043e\u0442\u043c\u0435\u043d\u044b \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b          heavyOperationPart() \/\/ \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f    } catch(e: CancellationException) {        releaseResources()  \/\/ \u041e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0430\u0435\u043c \u0440\u0435\u0441\u0443\u0440\u0441\u044b        \/\/ \u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0435\u0440\u0435\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u043e\u0442\u043c\u0435\u043d\u0443        throw e    } catch (e: Exception) {        log.error(\"\u0447\u0442\u043e-\u0442\u043e \u0443\u043f\u0430\u043b\u043e\", e)    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<h2>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a<\/h2>\n<h3>Try .. catch<\/h3>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"kotlin\">class WorkerInvoker {    private val realWorker = RealWorker()    suspend fun startWorks() {        realWorker.doWork()    }}class RealWorker {    suspend fun doWork() = withContext(Dispatchers.Default) {        launch {            delay(Duration.ofSeconds(2))        }    }}suspend fun main() {    val workerInvoker = WorkerInvoker()    workerInvoker.startWorks()}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e \u0447\u0442\u043e \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <em>RealWorker.doWork<\/em> <a href=\"https:\/\/kotlinlang.org\/api\/kotlinx.coroutines\/kotlinx-coroutines-core\/kotlinx.coroutines\/launch.html#\" rel=\"noopener nofollow\"><em>launch<\/em><\/a> \u0437\u0430\u043f\u0443\u0441\u043a\u0435\u0442 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0443 \u0431\u0435\u0437 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0443 <a href=\"https:\/\/habr.com\/ru\/article\/edit\/1067510\/\" rel=\"noopener nofollow\">Structured Concurrency<\/a> \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f <em>RealWorker.doWork, <\/em>\u043f\u043e\u0442\u043e\u043c <em>WorkerInvoker.startWorks <\/em>\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044f <em>main.<\/em> <em> <\/em><\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"kotlin\">class RealWorker {    suspend fun doWork() = withContext(Dispatchers.Default) {        launch {            delay(Duration.ofSeconds(2))            throw Exception(\"doWork Exception\")        }    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u043c \u0442\u0430\u043a\u043e\u0439 \u0442\u0440\u0435\u0439\u0441:<\/p>\n<pre><code class=\"kotlin\">Exception in thread \"main\" java.lang.Exception: DoWork Exceptionat ru.voskhod.RealWorker$doWork$2$1.invokeSuspend(Main.kt:23)at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34)  ....    <\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u041c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434:<\/p>\n<pre><code class=\"kotlin\">suspend fun doWork() = withContext(Dispatchers.Default) {        try {            launch {                delay(Duration.ofSeconds(2))                throw Exception(\"DoWork Exception\")            }        } catch (e: Exception) {            e.printStackTrace()            throw Exception(\"RealWorker Exception\")        }    }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u0422\u0440\u0435\u0439\u0441 \u043d\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f:<\/p>\n<pre><code class=\"kotlin\">Exception in thread \"main\" java.lang.Exception: DoWork Exceptionat ru.voskhod.RealWorker$doWork$2$1.invokeSuspend(Main.kt:24)at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34)  ....<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u041c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0435\u0449\u0451 \u0440\u0430\u0437:<\/p>\n<pre><code class=\"kotlin\">class WorkerInvoker {    private val realWorker = RealWorker()    suspend fun startWorks() {        try {            realWorker.doWork()        } catch (e: Exception) {            e.printStackTrace()            throw Exception(\"WorkerInvoker Exception\")        }    }}class RealWorker {    suspend fun doWork() = withContext(Dispatchers.Default) {        launch {            delay(Duration.ofSeconds(2))            throw Exception(\"DoWork Exception\")        }    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u0412 \u0432\u044b\u0432\u043e\u0434\u0435:<\/p>\n<pre><code class=\"kotlin\">java.lang.Exception: DoWork Exceptionat ru.voskhod.RealWorker$doWork$2$1.invokeSuspend(Main.kt:29)at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34)r.kt:704)      ....Exception in thread \"main\" java.lang.Exception: WorkerInvoker Exceptionat ru.voskhod.WorkerInvoker.doWork(Main.kt:20)at ru.voskhod.WorkerInvoker$doWork$1.invokeSuspend(Main.kt)at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34)at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWithInternal(DispatchedContinuation.kt:278)at kotlinx.coroutines.DispatchedCoroutine.afterResume(Builders.common.kt:588)  ....<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0447\u0435\u043c\u0443 \u0436\u0435 \u0441 <em>try .. catch <\/em>\u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <em>RealWorker.doWork <\/em>\u043d\u0435 \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u043b, \u0430 \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <em>WorkerInvoker.doWork<\/em>? <\/p>\n<p>\u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e <em>launch <\/em>\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0443 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e \u0438 \u043a \u043c\u043e\u043c\u0435\u043d\u0442\u0443 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f <em>launch-<\/em>\u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u043a\u043e\u0434 \u0431\u043b\u043e\u043a\u0430 <em>RealWorker.doWork <\/em>\u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d. \u041a\u043e\u0440\u0443\u0442\u0438\u043d\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f <em>RealWorker.doWork <\/em>\u043f\u0440\u043e\u0441\u0442\u043e \u0436\u0434\u0435\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043a\u043e\u0440\u0443\u0442\u0438\u043d. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0436\u0435 \u0441 <em>WorkerInvoker.doWork <\/em>\u0432 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0432\u044b\u0437\u043e\u0432\u0430 <em>realWorker.doWork()<\/em>.<\/p>\n<h3>CoroutineExceptionHandler<\/h3>\n<p>\u0414\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439, \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0449\u0438\u0439 \u0432 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430\u0445 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043e\u0431\u044a\u0435\u043a\u0442 <em>CoroutineExceptionHandler<\/em>. <\/p>\n<p>\u0415\u0441\u0442\u044c \u0434\u0432\u0430 \u043c\u043e\u043c\u0435\u043d\u0442\u044b, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441<strong> <\/strong><em>CoroutineExceptionHandler:<\/em><\/p>\n<ul>\n<li>\n<p><em>CoroutineExceptionHandler<\/em> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 kotlin runtime \u0438 \u043f\u043e\u0442\u043e\u043a \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u043d \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f. \u0422\u043e \u0435\u0441\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c \u0438 \u0431\u044b\u0441\u0442\u0440\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0442\u044c\u0441\u044f<\/p>\n<\/li>\n<li>\n<p><em>CoroutineExceptionHandler <\/em>\u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 <strong>\u0442\u043e\u043b\u044c\u043a\u043e <\/strong>\u0435\u0441\u043b\u0438 \u0435\u0433\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0432 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0435 \u0432\u0435\u0440\u0445\u043d\u0435\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f (\u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0435). \u0415\u0441\u043b\u0438 \u0435\u0433\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0432 \u0434\u043e\u0447\u0435\u0440\u043d\u0435\u0439 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0435 \u2014 \u043e\u043d\u00a0<strong>\u043d\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442:<\/strong><\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"kotlin\">\/\/ \u0422\u0430\u043a \u0434\u0435\u043b\u044f\u0442\u044c \u043d\u0435\u043b\u044c\u0437\u044f!!class RealWorker {    suspend fun doWork() = withContext(Dispatchers.Default) {        withContext(CoroutineExceptionHandler { ctx, ex -&gt;            println(\"Exception $ex thrown from coroutine context $ctx\")        }) {            launch {                delay(Duration.ofSeconds(2))                throw Exception(\"DoWork Exception1\")            }        }    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u041d\u043e \u0432\u044b\u0445\u043e\u0434\u0435 \u0432\u0441\u0435 \u0442\u0430\u043a \u0436\u0435:<\/p>\n<pre><code class=\"kotlin\">Exception in thread \"main\" java.lang.Exception: DoWork Exception1at ru.voskhod.RealWorker$doWork$2$2$1.invokeSuspend(Main.kt:34)at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34).kt:704)    .....<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f <em>CoroutineExceptionHandler<\/em> \u043d\u0430\u0434\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u044e \u043a\u043e\u0440\u0443\u0442\u0438\u043d:<\/p>\n<pre><code class=\"kotlin\">class RealWorker {    suspend fun doWork() = withContext(Dispatchers.Default) {        val handler = CoroutineExceptionHandler { ctx, ex -&gt;            println(\"Exception $ex thrown from coroutine context $ctx\")        }        val scope = CoroutineScope(SupervisorJob() + handler)        val job = scope.launch {            delay(Duration.ofSeconds(2))            throw Exception(\"DoWork Exception1\")        }        job.join() \/\/ \u0418\u0435\u0440\u0430\u0440\u0445\u0438\u044f \u043d\u043e\u0432\u0430\u044f, \u043d\u0443\u0436\u043d\u043e \u044f\u0432\u043d\u043e \u0434\u043e\u0436\u0438\u0434\u0430\u0442\u044c\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f job    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0430\u0441\u044c \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438 \u0432\u044b\u0432\u0435\u043b\u0430:<\/p>\n<pre><code class=\"kotlin\">&gt; Task :org.test.sample.MainKt.main()Exception java.lang.Exception: DoWork Exception1 thrown from coroutine context [org.test.sample.RealWorker$doWork$2$invokeSuspend$$inlined$CoroutineExceptionHandler$1@7f05f394, StandaloneCoroutine{Cancelling}@c68c8d1, Dispatchers.Default]<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u041d\u0430\u043f\u043e\u043c\u043d\u044e, \u0447\u0442\u043e \u043f\u0440\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f, \u043e\u0442\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0432\u0441\u044f \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u044f \u043a\u043e\u0440\u0443\u0442\u0438\u043d. \u0415\u0441\u043b\u0438 \u043d\u0435 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0442\u044c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u0438\u043b\u0438 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u0441\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0441\u0442\u043e\u0438\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <em>CoroutineExceptionHandler<\/em> \u0432 \u0441\u0432\u044f\u0437\u043a\u0435 \u0441 <em>SupervisorJob()\/supervisorScope<\/em>:<\/p>\n<pre><code class=\"kotlin\">suspend fun doWork() = withContext(Dispatchers.Default) {        val handler = CoroutineExceptionHandler { ctx, ex -&gt;            println(\"Exception $ex thrown from coroutine context $ctx\")        }        val scope = CoroutineScope(SupervisorJob() + handler)        val jobList = with(scope) {            listOf(                launch {                    supervisorScope {                        launch {                            delay(Duration.ofSeconds(2))                            throw Exception(\"DoWork Exception1\")                        }                        launch {                            delay(Duration.ofSeconds(3))                            throw Exception(\"DoWork Exception2\")                        }                    }                },                launch {                    delay(Duration.ofMillis(400))                    throw Exception(\"DoWork Exception3\")                }            )        }        jobList.joinAll()    }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<p>\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0432\u044b\u0432\u0435\u0434\u0435\u0442 \u0432\u0441\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"kotlin\">&gt; Task :org.test.sample.MainKt.main()Exception java.lang.Exception: DoWork Exception3 thrown from coroutine context [org.test.sample.RealWorker$doWork$2$invokeSuspend$$inlined$CoroutineExceptionHandler$1@64f0b65b, StandaloneCoroutine{Cancelling}@2dcedeb, Dispatchers.Default]Exception java.lang.Exception: DoWork Exception1 thrown from coroutine context [org.test.sample.RealWorker$doWork$2$invokeSuspend$$inlined$CoroutineExceptionHandler$1@64f0b65b, StandaloneCoroutine{Cancelling}@3444aebc, Dispatchers.Default]Exception java.lang.Exception: DoWork Exception2 thrown from coroutine context [org.test.sample.RealWorker$doWork$2$invokeSuspend$$inlined$CoroutineExceptionHandler$1@64f0b65b, StandaloneCoroutine{Cancelling}@29cbffc0, Dispatchers.Default]<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><span class=\"sc-logo-wrapper icon-only\"><\/span><\/a><\/div><\/pre>\n<h2>\u0421\u0441\u044b\u043b\u043a\u0438 \u0438 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u043d\u043e\u0441\u0442\u0438<\/h2>\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/otus\/articles\/854090\/?ysclid=mtl6d5np1p753192883\" rel=\"noopener nofollow\">\u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u0430\u044f \u0448\u043f\u0430\u0440\u0433\u0430\u043b\u043a\u0430 \u043f\u043e \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430\u043c Kotlin<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/kotlinlang.org\/api\/kotlinx.coroutines\/kotlinx-coroutines-core\/\" rel=\"noopener nofollow\">kotlinx-coroutines-core<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/1068314\/\" rel=\"noopener nofollow\">\u0428\u043f\u0430\u0440\u0433\u0430\u043b\u043a\u0430: Structured Concurrency \u0438 \u043e\u0442\u043c\u0435\u043d\u0430 \u043a\u043e\u0440\u0443\u0442\u0438\u043d<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/companies\/otus\/articles\/1065504\/\" rel=\"noopener nofollow\">\u041a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u043d\u0430\u00a0\u0431\u044d\u043a\u0435\u043d\u0434\u0435: \u0441\u0435\u043c\u044c \u043e\u0448\u0438\u0431\u043e\u043a, \u0438\u0437\u2011\u0437\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u0430\u0434\u0430\u0435\u0442 \u043d\u0435\u00a0\u0442\u043e\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0438 \u0432\u0438\u0441\u044f\u0442 \u043d\u0435\u00a0\u0442\u0435 \u0437\u0430\u0434\u0430\u0447\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/kotlinlang.org\/docs\/exception-handling.html\" rel=\"noopener nofollow\">Coroutine exceptions handling<\/a><\/p>\n<\/li>\n<\/ul>\n<h4><\/h4>\n<h3><\/h3>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1090314\/\">https:\/\/habr.com\/ru\/articles\/1090314\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0420\u0430\u043d\u0435\u0435 \u043c\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c c \u043f\u0440\u043e\u0431\u0435\u043c\u0430\u0442\u0438\u043a\u043e\u0439, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u0432\u0435\u043b\u0430 \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430 Kotlin Coroutines \u0430 \u0442\u0430\u043a \u0436\u0435 \u0441 \u0442\u0435\u043c\u0438 \u0438\u0434\u0435\u044f\u043c\u0438, \u0447\u0442\u043e \u0431\u044b\u043b\u0438 \u0437\u0430\u043b\u043e\u0436\u0435\u043d\u044b \u043f\u0440\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u0414\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u0440\u044bC\u043c\u044b\u0441\u043b \u0434\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u0440\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 &#8212; \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043d\u0430 \u043a\u0430\u043a\u043e\u043c-\u0442\u043e \u043f\u043e\u0442\u043e\u043a\u0435. \u0414\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u0440 &#8212; \u044d\u0442\u043e \u0438 \u0435\u0441\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043f\u0443\u043b \u043f\u043e\u0442\u043e\u043a\u043e\u0432.\u041a\u0430\u043a \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0438\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043a\u043e\u0440\u0443\u0442\u0438\u043d, \u043e\u0431\u044a\u0435\u043a\u0442 \u043a \u0434\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u0440\u0443 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u0438\u0437 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b.val currentDispatcher = coroutineContext[ContinuationInterceptor] as CoroutineDispatcher\u0423\u043a\u0430\u0437\u0430\u0442\u044c \u0434\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u0440, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430 \u043c\u043e\u0436\u043d\u043e \u044f\u0432\u043d\u043e \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u0438\u043b\u0438 \u043f\u0440\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0438 suspend-\u0444\u0443\u043d\u043a\u0446\u0438\u0438:launc (dispatcher) {   &#8230; }suspend fun helloWorld() = withContext(dispatcher) {  &#8230;.}\u0415\u0441\u043b\u0438 \u0434\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u0440 \u044f\u0432\u043d\u043e \u043d\u0435 \u0437\u0430\u0434\u0430\u0435\u0442\u0441\u044f &#8212; \u0434\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0439 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b.\u0418\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 coroutine runtime \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0434\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u0440\u044b:Dispatchers.Default \u041f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439, \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0445 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043d\u0430 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 (CPU).\u00a0\u0420\u0430\u0437\u043c\u0435\u0440 \u043f\u0443\u043b\u0430 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u044f\u0434\u0435\u0440 \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435.\u00a0Dispatchers.Main\u0414\u043b\u044f Android \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 (UI thread).\u00a0\u0412\u0430\u0436\u043d\u043e \u0438\u0437\u0431\u0435\u0433\u0430\u0442\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430.\u00a0\u041d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u0430\u0445 (\u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 Main-\u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440).Dispatchers.IO\u041f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 (\u0432\u0432\u043e\u0434\u0430-\u0432\u044b\u0432\u043e\u0434\u0430, \u0447\u0442\u0435\u043d\u0438\u0435\/\u0437\u0430\u043f\u0438\u0441\u044c \u0444\u0430\u0439\u043b\u043e\u0432, \u0434\u043e\u0441\u0442\u0443\u043f \u043a Shared Preferences \u0438 \u0442.\u0434.).\u00a0\u0420\u0430\u0437\u043c\u0435\u0440 \u043f\u0443\u043b\u0430 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 64 (\u0438\u043b\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0447\u0438\u0441\u043b\u0443 \u044f\u0434\u0435\u0440, \u0435\u0441\u043b\u0438 \u0438\u0445 \u0431\u043e\u043b\u044c\u0448\u0435 64).\u00a0\u041f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0445 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438.\u00a0Dispatchers.Unconfined\u041a\u043e\u0440\u0443\u0442\u0438\u043d\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c \u0436\u0435 \u043f\u043e\u0442\u043e\u043a\u0435, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u044b\u043b\u0430 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430; \u0441\u043c\u0435\u043d\u0430 \u043f\u043e\u0442\u043e\u043a\u0430 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0442\u0438 \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u0437\u043e\u0432\u0430 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0439 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u0438\u0437 \u0434\u043e\u0447\u0435\u0440\u043d\u0435\u0439.\u00a0\u041f\u043e\u043b\u0435\u0437\u0435\u043d \u0434\u043b\u044f \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u043e\u0432.\u00a0\u041d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0414\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u0440 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e:val executor = Executors.newFixedThreadPool(2)val customDispatcher = executor.asCoroutineDispatcher()\u043e\u0434\u043d\u0430\u043a\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a \u043d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u044b\u043c \u0446\u0438\u043a\u043b\u043e\u043c \u0434\u0438\u0441\u043f\u0430\u0442\u0447\u0435\u0440\u0430 \u0432 \u0440\u0443\u0447\u043d\u0443\u044e. \u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u043c\u044b\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0431\u0430\u0437\u0435 Dispatchers.Default  \u0438\u043b\u0438  Dispatchers.IO \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0443\u043b\u0430 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u044b\u0437\u043e\u0432\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 limitedParallelismval confined = Dispatchers.Default.limitedParallelism(1, &#171;incrementDispatcher&#187;)var counter = 0\/\/ Invoked from arbitrary coroutineslaunch(confined) {    \/\/ This increment is sequential and race-free    ++counter}\u041d\u044e\u0430\u043d\u0441\u044b \u0440\u0430\u0431\u043e\u0442\u044b c \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430\u043c\u0438, \u043f\u0440\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0437\u0430\u0431\u044b\u0432\u0430\u0442\u044cThreadLocal &#8212; \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435\u0412\u044b\u0437\u043e\u0432 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b &#8212; \u044d\u0442\u043e \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f. \u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u0437\u043e\u0432\u0430 suspend-\u043c\u0435\u0442\u043e\u0434\u0430 \u043f\u043e\u0442\u043e\u043a, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0439 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0443 \u0432 \u043e\u0431\u0449\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f. suspend fun helloWorld()  {    val threadLocal = ThreadLocal&lt;String&gt;()    threadLocal.set(&#171;main&#187;)    println(&#171;thread local value: &#8216;${threadLocal.get()}'&#187;)    delay(2000)    \/\/ \u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043a\u0430\u043a &#171;main&#187;, \u0442\u0430\u043a \u0438 null    println(&#171;thread local value: &#8216;${threadLocal.get()}'&#187;)}\u0415\u0441\u043b\u0438 \u0432 \u043b\u043e\u0433\u0438\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432\u0441\u0435 \u0436\u0435 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 \u043f\u043e\u0442\u043e\u043a\u043e\u043c, \u0441\u0442\u043e\u0438\u0442 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435\u043c asContextElement \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043a \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0443 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b: suspend fun helloWorld() = withContext(Dispatchers.Default) {     val threadLocal = ThreadLocal&lt;String&gt;()     threadLocal.set(&#171;main&#187;)     launch(threadLocal.asContextElement()) {         println(&#171;thread local value: &#8216;${threadLocal.get()}'&#187;)         delay(2000)         println(&#171;thread local value: &#8216;${threadLocal.get()}'&#187;)     } }\u041f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b\u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u043c\u0435\u0442\u043e\u0434\u0430  job.cancel()\u00a0 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u0434\u0432\u0435  \u0432\u0435\u0449\u0438:\u0412\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0439 \u0444\u043b\u0430\u0433 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f Job\u00a0\u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0441\u0442\u0430\u0442\u0443\u0441 Cancelling.Job \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u0441\u043f\u0438\u0441\u043a\u0443 \u0441\u0432\u043e\u0438\u0445 \u0434\u0435\u0442\u0435\u0439 \u0438 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u00a0cancel()\u00a0\u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u043d\u0438\u0445.\u041d\u0430 \u044d\u0442\u043e\u043c \u0440\u0430\u0431\u043e\u0442\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 cancel()\u00a0\u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f. \u041c\u0435\u0442\u043e\u0434 \u043d\u0435 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u0434 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0438 \u0441\u0430\u043c \u043f\u043e \u0441\u0435\u0431\u0435 \u043d\u0435 \u0431\u0440\u043e\u0441\u0430\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0432 \u0442\u043e\u043c \u043c\u0435\u0441\u0442\u0435, \u0433\u0434\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430. \u0417\u0430 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u043a\u043e\u0440\u0443\u0442\u0438\u043d \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 kotlin runtime. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u0430\u043c\u0430 \u043e\u0442\u043c\u0435\u043d\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043d\u0435 \u0441\u0440\u0430\u0437\u0443, \u0430 \u0432 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0439 \u0442\u043e\u0447\u043a\u0435 \u0432\u044b\u0437\u043e\u0432\u0430 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b  (suspension point). \u0415\u0441\u043b\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u043e\u043b\u0433\u0430\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u043a\u043e\u0440\u0443\u0442\u0438\u043d &#8212; \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0434\u0432\u0438\u0441\u043d\u0443\u0442\u044c. \u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u0434\u043e\u043b\u0433\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043d\u0443\u0436\u043d\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0441\u0442\u0430\u0442\u0443\u0441 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u0447\u0435\u0440\u0435\u0437 \u0432\u044b\u0437\u043e\u0432 ensureActive(). while (true) {    ensureActive()  \/\/ suspend-\u0444\u0443\u043d\u043a\u0446\u0438\u044f; \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0435 \u0431\u044b\u043b\u043e \u043b\u0438 \u043e\u0442\u043c\u0435\u043d\u044b \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b      heavyOperationPart() \/\/ \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f}CancellationException\u0414\u043b\u044f \u0441\u0438\u0433\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0435, \u0442\u043e\u0433\u043e \u0447\u0442\u043e \u043e\u043d\u0430 \u0431\u044b\u043b\u0430 \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u0430 kotlin runtime \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 CancellationException. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0432\u044b\u043b\u0435\u0442\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0447\u043a\u0438 \u0432\u044b\u0437\u043e\u0432\u0430 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b (suspension point). \u0415\u0441\u043b\u0438 \u0442\u0430\u043a\u043e\u0432\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u043d\u0435\u0442 &#8212; \u0442\u043e \u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e.CancellationException &#8212; \u043e\u0431\u044b\u0447\u043d\u043e\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 \u0431\u043b\u043e\u043a\u0435 catch. \u041d\u043e CancellationException \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u0434\u0430\u043b\u044c\u0448\u0435. while (true) {    try {        ensureActive()  \/\/ suspend-\u0444\u0443\u043d\u043a\u0446\u0438\u044f; \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0435 \u0431\u044b\u043b\u043e \u043b\u0438 \u043e\u0442\u043c\u0435\u043d\u044b \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b          heavyOperationPart() \/\/ \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f    } catch(e: CancellationException) {        releaseResources()  \/\/ \u041e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0430\u0435\u043c \u0440\u0435\u0441\u0443\u0440\u0441\u044b        \/\/ \u041e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0435\u0440\u0435\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u043e\u0442\u043c\u0435\u043d\u0443        throw e    } catch (e: Exception) {        log.error(&#171;\u0447\u0442\u043e-\u0442\u043e \u0443\u043f\u0430\u043b\u043e&#187;, e)    }}\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043aTry .. catch\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440:class WorkerInvoker {    private val realWorker = RealWorker()    suspend fun startWorks() {        realWorker.doWork()    }}class RealWorker {    suspend fun doWork() = withContext(Dispatchers.Default) {        launch {            delay(Duration.ofSeconds(2))        }    }}suspend fun main() {    val workerInvoker = WorkerInvoker()    workerInvoker.startWorks()}\u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e \u0447\u0442\u043e \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 RealWorker.doWork launch \u0437\u0430\u043f\u0443\u0441\u043a\u0435\u0442 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0443 \u0431\u0435\u0437 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0443 Structured Concurrency \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f RealWorker.doWork, \u043f\u043e\u0442\u043e\u043c WorkerInvoker.startWorks \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044f main.  \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440:class RealWorker {    suspend fun doWork() = withContext(Dispatchers.Default) {        launch {            delay(Duration.ofSeconds(2))            throw Exception(&#171;doWork Exception&#187;)        }    }}\u041f\u043e\u043b\u0443\u0447\u0438\u043c \u0442\u0430\u043a\u043e\u0439 \u0442\u0440\u0435\u0439\u0441:Exception in thread &#171;main&#187; java.lang.Exception: DoWork Exceptionat ru.voskhod.RealWorker$doWork$2$1.invokeSuspend(Main.kt:23)at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34)  &#8230;.    \u041c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434:suspend fun doWork() = withContext(Dispatchers.Default) {        try {            launch {                delay(Duration.ofSeconds(2))                throw Exception(&#171;DoWork Exception&#187;)            }        } catch (e: Exception) {            e.printStackTrace()            throw Exception(&#171;RealWorker Exception&#187;)        }    }\u0422\u0440\u0435\u0439\u0441 \u043d\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f:Exception in thread &#171;main&#187; java.lang.Exception: DoWork Exceptionat ru.voskhod.RealWorker$doWork$2$1.invokeSuspend(Main.kt:24)at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34)  &#8230;.\u041c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0435\u0449\u0451 \u0440\u0430\u0437:class WorkerInvoker {    private val realWorker = RealWorker()    suspend fun startWorks() {        try {            realWorker.doWork()        } catch (e: Exception) {            e.printStackTrace()            throw Exception(&#171;WorkerInvoker Exception&#187;)        }    }}class RealWorker {    suspend fun doWork() = withContext(Dispatchers.Default) {        launch {            delay(Duration.ofSeconds(2))            throw Exception(&#171;DoWork Exception&#187;)        }    }}\u0412 \u0432\u044b\u0432\u043e\u0434\u0435:java.lang.Exception: DoWork Exceptionat ru.voskhod.RealWorker$doWork$2$1.invokeSuspend(Main.kt:29)at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34)r.kt:704)      &#8230;.Exception in thread &#171;main&#187; java.lang.Exception: WorkerInvoker Exceptionat ru.voskhod.WorkerInvoker.doWork(Main.kt:20)at ru.voskhod.WorkerInvoker$doWork$1.invokeSuspend(Main.kt)at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34)at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWithInternal(DispatchedContinuation.kt:278)at kotlinx.coroutines.DispatchedCoroutine.afterResume(Builders.common.kt:588)  &#8230;.\u041f\u043e\u0447\u0435\u043c\u0443 \u0436\u0435 \u0441 try .. catch \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 RealWorker.doWork \u043d\u0435 \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u043b, \u0430 \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 WorkerInvoker.doWork? \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e launch \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0443 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e \u0438 \u043a \u043c\u043e\u043c\u0435\u043d\u0442\u0443 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f launch-\u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u043a\u043e\u0434 \u0431\u043b\u043e\u043a\u0430 RealWorker.doWork \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d. \u041a\u043e\u0440\u0443\u0442\u0438\u043d\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f RealWorker.doWork \u043f\u0440\u043e\u0441\u0442\u043e \u0436\u0434\u0435\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043a\u043e\u0440\u0443\u0442\u0438\u043d. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0436\u0435 \u0441 WorkerInvoker.doWork \u0432 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0432\u044b\u0437\u043e\u0432\u0430 realWorker.doWork().CoroutineExceptionHandler\u0414\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439, \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0449\u0438\u0439 \u0432 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430\u0445 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043e\u0431\u044a\u0435\u043a\u0442 CoroutineExceptionHandler. \u0415\u0441\u0442\u044c \u0434\u0432\u0430 \u043c\u043e\u043c\u0435\u043d\u0442\u044b, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 CoroutineExceptionHandler:CoroutineExceptionHandler \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 kotlin runtime \u0438 \u043f\u043e\u0442\u043e\u043a \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u043d \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f. \u0422\u043e \u0435\u0441\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043f\u043e\u0442\u043e\u043a\u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c \u0438 \u0431\u044b\u0441\u0442\u0440\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0442\u044c\u0441\u044fCoroutineExceptionHandler \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u0435\u0433\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0432 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0435 \u0432\u0435\u0440\u0445\u043d\u0435\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f (\u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0435). \u0415\u0441\u043b\u0438 \u0435\u0433\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0432 \u0434\u043e\u0447\u0435\u0440\u043d\u0435\u0439 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0435 \u2014 \u043e\u043d\u00a0\u043d\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442:\/\/ \u0422\u0430\u043a \u0434\u0435\u043b\u044f\u0442\u044c \u043d\u0435\u043b\u044c\u0437\u044f!!class RealWorker {    suspend fun doWork() = withContext(Dispatchers.Default) {        withContext(CoroutineExceptionHandler { ctx, ex -&gt;            println(&#171;Exception $ex thrown from coroutine context $ctx&#187;)        }) {            launch {                delay(Duration.ofSeconds(2))                throw Exception(&#171;DoWork Exception1&#187;)            }        }    }}\u041d\u043e \u0432\u044b\u0445\u043e\u0434\u0435 \u0432\u0441\u0435 \u0442\u0430\u043a \u0436\u0435:Exception in thread &#171;main&#187; java.lang.Exception: DoWork Exception1at ru.voskhod.RealWorker$doWork$2$2$1.invokeSuspend(Main.kt:34)at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:34).kt:704)    &#8230;..\u0414\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f CoroutineExceptionHandler \u043d\u0430\u0434\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u044e \u043a\u043e\u0440\u0443\u0442\u0438\u043d:class RealWorker {    suspend fun doWork() = withContext(Dispatchers.Default) {        val handler = CoroutineExceptionHandler { ctx, ex -&gt;            println(&#171;Exception $ex thrown from coroutine context $ctx&#187;)        }        val scope = CoroutineScope(SupervisorJob() +&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-497318","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/497318","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=497318"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/497318\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=497318"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=497318"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=497318"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}