{"id":45962,"date":"2022-03-21T17:34:32","date_gmt":"2022-03-21T08:34:32","guid":{"rendered":"https:\/\/www.charlezz.com\/?p=45962"},"modified":"2022-03-21T17:34:32","modified_gmt":"2022-03-21T08:34:32","slug":"%ec%b2%98%ec%9d%8c-%ec%8b%9c%ec%9e%91%ed%95%98%eb%8a%94-%ec%bd%94%eb%a3%a8%ed%8b%b4-%ea%b8%b0%eb%b3%b8%ec%a0%81%ec%9d%b8-%ec%9a%a9%ec%96%b4%ec%99%80-%ec%9d%b4%ed%95%b4","status":"publish","type":"post","link":"https:\/\/charlezz.com\/?p=45962","title":{"rendered":"\ucc98\uc74c \uc2dc\uc791\ud558\ub294 \ucf54\ub8e8\ud2f4, \uae30\ubcf8\uc801\uc778 \uc6a9\uc5b4\uc640 \uc774\ud574"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\">\ucf54\ub8e8\ud2f4(Coroutines)\uc774\ub780?<\/h1>\n\n\n\n<p><em>\ucf54\ub8e8\ud2f4<\/em>\uc740 \ube44\ub3d9\uae30\uc801\uc73c\ub85c \uc2e4\ud589\ub418\ub294 \ucf54\ub4dc\ub97c \uac04\uc18c\ud654\ud558\uae30 \uc704\ud574 Android\uc5d0\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \ub3d9\uc2dc \uc2e4\ud589 \uc124\uacc4 \ud328\ud134\uc774\ub2e4.<\/p>\n\n\n\n<p>\ucf54\ub8e8\ud2f4\uc740 \ub2e4\uc74c\uacfc \uac19\uc740 \ud2b9\uc9d5\uc744 \uac16\ub294\ub2e4.<\/p>\n\n\n\n<ul><li>\uacbd\ub7c9\ud654<\/li><li>\uba54\ubaa8\ub9ac \ub204\uc218 \uac10\uc18c<\/li><li>\uacc4\uce35\uc801 \uad6c\uc870\ub97c \ud1b5\ud55c \ucde8\uc18c \uc804\ub2ec<\/li><li>Jetpack\uacfc\uc758 \ud1b5\ud569<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Suspend function<\/h3>\n\n\n\n<p><strong>suspend(\uc720\uc608\ud558\ub2e4, \uc5f0\uae30\ud558\ub2e4) vs block(\ub9c9\ub2e4, \ucc28\ub2e8\ud558\ub2e4)<\/strong><\/p>\n\n\n\n<p>blocking\uacfc suspending\uc758 \ucc28\uc774\uc5d0 \ub300\ud574\uc11c \uba3c\uc800 \uc54c\uc544\ubcf4\uc790.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"872\" height=\"344\" src=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2022\/03\/www.charlezz.com-1-t28sfv0jdkbtnaa0eki3pw.png\" alt=\"\" class=\"wp-image-45967\" srcset=\"https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2022\/03\/www.charlezz.com-1-t28sfv0jdkbtnaa0eki3pw.png 872w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2022\/03\/www.charlezz.com-1-t28sfv0jdkbtnaa0eki3pw-300x118.png 300w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2022\/03\/www.charlezz.com-1-t28sfv0jdkbtnaa0eki3pw-768x303.png 768w\" sizes=\"(max-width: 872px) 100vw, 872px\" \/><figcaption><em>BLOCKING : \ud568\uc218B\ub97c \uc218\ud589\ud558\uae30 \uc704\ud574\uc11c\ub294 \ud568\uc218A\uac00 \uba3c\uc800 \ub05d\ub098\uc57c \ud55c\ub2e4.<\/em><\/figcaption><\/figure><\/div>\n\n\n\n<p>\ub2e8\uc77c \uc4f0\ub808\ub4dc\uc5d0\uc11c \ub124\ud2b8\uc6cc\ud06c \uc694\uccad(FUNCTION A)\uacfc \uac19\uc740 \uc791\uc5c5\uc744 \uc218\ud589\ud558\ub2e4 \ubcf4\uba74 \uc751\ub2f5\uc744 \uc5bb\ub294\ub370\uae4c\uc9c0 \uae34 \uc2dc\uac04\uc774 \ud544\uc694\ud560 \uc218 \uc788\ub2e4. \uc774 \ub3d9\uc548 \ud574\ub2f9 \uc4f0\ub808\ub4dc\ub294 \b<strong>\ube14\ub85d\uc0c1\ud0dc(blocked)<\/strong>\uac00 \ub418\uace0 \ub2e4\uc74c \uc791\uc5c5(FUNCTION B)\uc740 \ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc774 \ub05d\ub0a0 \ub54c\uae4c\uc9c0 \uae30\ub2e4\ub9ac\uac8c \ub41c\ub2e4. \uadf8\ub798\uc11c \uc77c\ubc18\uc801\uc73c\ub85c \ub2e4\uc911 \uc2a4\ub808\ub4dc\ub97c \uc0ac\uc6a9\ud558\uc5ec \ube44\ub3d9\uae30\uc801\uc73c\ub85c \uc791\uc5c5\uc744 \uc218\ud589\ud55c\ub2e4.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"850\" height=\"428\" src=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2022\/03\/www.charlezz.com-1-ogq6yfxxawg7-lvmkicn5g.png\" alt=\"\" class=\"wp-image-45968\" srcset=\"https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2022\/03\/www.charlezz.com-1-ogq6yfxxawg7-lvmkicn5g.png 850w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2022\/03\/www.charlezz.com-1-ogq6yfxxawg7-lvmkicn5g-300x151.png 300w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2022\/03\/www.charlezz.com-1-ogq6yfxxawg7-lvmkicn5g-768x387.png 768w\" sizes=\"(max-width: 850px) 100vw, 850px\" \/><figcaption><em>SUSPENDING: \ud568\uc218A\uac00 \uc2dc\uc791 \ub41c \ud6c4 \uc815\uc9c0(suspended) \ub420 \uc218 \uc788\uc73c\uba70, \ud568\uc218B\uac00 \uc218\ud589\ub418\uace0 \ub05d\ub09c \ub4a4 \ud568\uc218A\uac00 \uc7ac\uac1c(resume)\ub420 \uc218 \uc788\ub2e4. \uc989 \uc774 \uc4f0\ub808\ub4dc\ub294 \ud568\uc218A\uc5d0 \uc758\ud574 \ube14\ub77d\ub418\uc9c0 \uc54a\ub294\ub2e4.<\/em><\/figcaption><\/figure><\/div>\n\n\n\n<p>\ucf54\ub8e8\ud2f4\uc758 suspend \ud568\uc218\ub294 \ub124\ud2b8\uc6cc\ud06c \uc694\uccad(FUNCTION A)\uc744 \uc218\ud589\ud558\uace0 \uc4f0\ub808\ub4dc\uac00 \ube14\ub85d\ub418\ub294 \ub300\uc2e0 \ud558\ub358 \uc791\uc5c5\uc744 <strong>\uc815\uc9c0(suspended)<\/strong> \uc2dc\ud0a8\ub2e4. \uadf8\ub9ac\uace0 \ub2e4\ub978 \uc791\uc5c5\uc774 \ud574\ub2f9 \uc4f0\ub808\ub4dc\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub3c4\ub85d \ud55c\ub2e4. \ud558\ub098\uc758 \uc4f0\ub808\ub4dc\uc5d0\uc11c \uc5ec\ub7ec \uc791\uc5c5\uc744 \uc218\ud589\ud560 \uc218 \uc788\uc73c\ub2c8 \uc4f0\ub808\ub4dc\ub97c \ub9cc\ub4e4 \ud544\uc694\uac00 \uc5c6\ub2e4. \uc774\ub7ec\ud55c \uc774\uc720\ub85c \ucf54\ub8e8\ud2f4\uc744 <a href=\"https:\/\/www.charlezz.com\/?p=44634\">\uacbd\ub7c9\ud654 \ub41c \uc4f0\ub808\ub4dc(Light-weighted Thread)<\/a>\ub77c\uace0 \ud45c\ud604\ud558\uae30\ub3c4 \ud55c\ub2e4.<\/p>\n\n\n\n<p>Suspend \ud568\uc218\ub294 <strong>\uc2dc\uc791(Started)<\/strong>\ub418\uace0 <strong>\uc911\ub2e8(paused)<\/strong> \ub420 \uc218 \uc788\uc73c\uba70, \ub2e4\uc2dc <strong>\uc7ac\uac8c(Resume)<\/strong>\ud560 \uc218 \uc788\ub294 \ud568\uc218\ub97c \uc758\ubbf8 \ud55c\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">CoroutineContext<\/h2>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1002\" height=\"826\" src=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2022\/03\/www.charlezz.com-1-pf93e3va3mphjhtmho-j1a.png\" alt=\"\" class=\"wp-image-45969\" srcset=\"https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2022\/03\/www.charlezz.com-1-pf93e3va3mphjhtmho-j1a.png 1002w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2022\/03\/www.charlezz.com-1-pf93e3va3mphjhtmho-j1a-300x247.png 300w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2022\/03\/www.charlezz.com-1-pf93e3va3mphjhtmho-j1a-768x633.png 768w\" sizes=\"(max-width: 1002px) 100vw, 1002px\" \/><figcaption><em>CoroutineContext\uac00 \uac00\uc9c0\uace0 \uc788\ub294 \uc815\ubcf4\ub97c \uac04\ub2e8\ud788 \ub3c4\uc2dd\ud654\ud55c \uc774\ubbf8\uc9c0<\/em><\/figcaption><\/figure><\/div>\n\n\n\n<p>CoroutineContext\ub294 \uac1c\ub150\uc801\uc73c\ub85c\ub294 map \ub610\ub294 set\uacfc \uc720\uc0ac\ud558\ub2e4. CoroutineContext\ub294 Job, CoroutineName, CorotuineDispatcher \ub4f1\uacfc \uac19\uc740 Element \uc778\uc2a4\ud134\uc2a4\ub97c <strong>\uc21c\uc11c\uac00 \uc788\ub294 Set<\/strong>(indexed set)\uc73c\ub85c \uad00\ub9ac \ud55c\ub2e4. \ud2b9\uc774\ud55c \uc810\uc740 \uac01 Element \ub610\ud55c CoroutineContext \uc774\uae30 \ub54c\ubb38\uc5d0 \uceec\ub809\uc158 \ub0b4\uc5d0 \uc788\ub294 \ubaa8\ub4e0 element\ub4e4 \ub610\ud55c \uceec\ub809\uc158\uc774 \ub41c\ub2e4. \uadf8\ub9ac\uace0 \ubaa8\ub4e0 element\uc5d0\ub294 \uc774\ub97c \uc2dd\ubcc4\ud558\uae30 \uc704\ud55c \uace0\uc720\ud55c Key\ub97c \uac00\uc9c0\uace0 \uc788\ub2e4. \uc774 \ubd80\ubd84\uc774 <strong>\uad6c\uc870\ud654\ub41c \ub3d9\uc2dc\uc131(<a href=\"https:\/\/kotlinlang.org\/docs\/coroutines-basics.html#structured-concurrency\" rel=\"noreferrer noopener\" target=\"_blank\">Structured Concurrency<\/a>)<\/strong>\uc744 \uad6c\ud604\ud558\uae30 \uc704\ud55c \uae30\ubc18 \uc694\uc18c\uac00 \ub41c\ub2e4.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Dispatchers<\/h3>\n\n\n\n<p>Dispatcher\ub97c \uc0ac\uc6a9\ud558\uc5ec \ucf54\ub8e8\ud2f4 \uc2e4\ud589\uc5d0 \uc0ac\uc6a9\ub418\ub294 \uc2a4\ub808\ub4dc\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4. \uae30\ubcf8\uc801\uc73c\ub85c \uc81c\uacf5\ud558\ub294 Dispatcher\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4.<\/p>\n\n\n\n<ul><li>Default: CPU \ucf54\uc5b4 \uc218\uc5d0 \ube44\ub840\ud558\ub294 \uc2a4\ub808\ub4dc \ud480\uc5d0\uc11c \uc218\ud589\ud55c\ub2e4. CPU \uc9d1\uc57d\uc801\uc778 \uc791\uc5c5\uc5d0 \uc801\ud569\ud558\ub2e4.<\/li><li>IO: \uc77c\ubc18\uc801\uc73c\ub85c IO \uc791\uc5c5\uc740 CPU\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce58\uc9c0 \uc54a\uc73c\ubbc0\ub85c, CPU \ucf54\uc5b4 \uc218\ubcf4\ub2e4 \ud6e8\uc52c \ub9ce\uc740 \uc2a4\ub808\ub4dc\ub97c \uac00\uc9c0\ub294 \uc2a4\ub808\ub4dc \ud480\uc5d0\uc11c \uc218\ud589\ud55c\ub2e4(\ucd5c\ub300 64\uac1c). Default dispatcher\uc640 \uc2a4\ub808\ub4dc\ub97c \uacf5\uc720\ud558\uae30 \ub54c\ubb38\uc5d0 Context switching\uc73c\ub85c \uc778\ud55c \uc624\ubc84\ud5e4\ub4dc\uac00 \uc5c6\ub2e4.<\/li><li>Unconfined: \ud574\ub2f9 \ucf54\ub8e8\ud2f4\uc744 \ud638\ucd9c\ud55c \ubd80\ubaa8\uc758 \uc4f0\ub808\ub4dc\uc5d0\uc11c \uc2e4\ud589 \ub610\ub294 \uc7ac\uac8c\ub41c\ub2e4.<\/li><li>newSingleThreadContext: \uc0c8\ub85c\uc6b4 \uc4f0\ub808\ub4dc\ub97c \uc0dd\uc131\ud55c\ub2e4.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">CoroutineScope<\/h2>\n\n\n\n<p>\ucf54\ub8e8\ud2f4\uc758 \ubc94\uc704\ub97c \uc815\uc758\ud55c\ub2e4. launch, async \ub4f1\uacfc \uac19\uc740 \ubaa8\ub4e0 \ucf54\ub8e8\ud2f4 \ube4c\ub354\ub294 CoroutineScope\uc758 \ud655\uc7a5\ud568\uc218\uc774\uba70, \ud574\ub2f9 CoroutineContext\ub97c \uc0c1\uc18d\ud558\uc5ec \ubaa8\ub4e0 element\uc640 cancellation(\ucde8\uc18c)\ub97c \uc790\ub3d9\uc73c\ub85c \uc804\ud30c\ud55c\ub2e4.<\/p>\n\n\n\n<p>\uc77c\ubc18\uc801\uc73c\ub85c CoroutineScope\uc758 \uc9c1\uc811\uc801\uc778 \uad6c\ud604\uc740 \uad8c\uc7a5\ud558\uc9c0 \uc54a\uc73c\uba70, \ub378\ub9ac\uac8c\uc774\uc158\uc5d0 \uc758\ud55c \uad6c\ud604\uc744 \uad8c\uc7a5\ud55c\ub2e4. \uad00\ub840\uc5d0 \ub530\ub77c Scope\ub0b4\uc758 Context\uc5d0\ub294 Cancellation\uc758 \uc804\ud30c\ub97c \ud3ec\ud568\ud55c \uad6c\uc870\ud654 \ub41c \ub3d9\uc2dc\uc131 \uc6d0\uce59\uc744 \uc801\uc6a9\ud558\uae30 \uc704\ud55c Job \uc778\uc2a4\ud134\uc2a4\uac00 \ud3ec\ud568\ub418\uc5b4\uc57c \ud55c\ub2e4.<\/p>\n\n\n\n<p>\uae30\ubcf8\uc801\uc778 \ucf54\ub8e8\ud2f4 \ube4c\ub354\uc758 \uc0ac\uc6a9\ubc95\uacfc \uadf8 \uc678\uc5d0 \ub2e4\uc591\ud55c \uacbd\uc6b0\uc5d0 \uc0ac\uc6a9\ub418\ub294 \ucf54\ub8e8\ud2f4 \ube4c\ub354\uc5d0 \ub300\ud574 \uc54c\uc544\ubcf4\uc790.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\uae30\ubcf8\uc801\uc778 Coroutine builder \uc885\ub958<\/h3>\n\n\n\n<ul><li>launch<\/li><li>runBlocking<\/li><li>async<\/li><\/ul>\n\n\n\n<p><strong>launch builder<\/strong><\/p>\n\n\n\n<p>\ud604\uc7ac \uc4f0\ub808\ub4dc\ub97c \ube14\ub85c\ud0b9\ud558\uc9c0 \uc54a\uace0 \uc0c8 \ucf54\ub8e8\ud2f4\uc744 \uc2dc\uc791\ud558\uba70, \uc774\uc5d0 \ub300\ud55c \ucc38\uc870\ub97c Job \uac1d\uccb4\ub85c \ubc18\ud658\ud55c\ub2e4. \uc774 Job\uc774 \ucde8\uc18c\ub418\uba74 \ucf54\ub8e8\ud2f4\uc774 \ucde8\uc18c \ub41c\ub2e4. CoroutineContext\ub294 \ud574\ub2f9 CoroutineScope\uc758 \uac83\uc744 \uc0c1\uc18d\ud558\uba70, launch \ud568\uc218\uc758 \ub9e4\uac1c\ubcc0\uc218\ub85c \ucd94\uac00\uc801\uc778 Context\ub97c \uc9c0\uc815\ud560 \uc218\ub3c4 \uc788\ub2e4. \ud574\ub2f9 Context\uc5d0 Dispatcher\ub098 \ub2e4\ub978 ContinuationInterceptor\uac00 \uc5c6\uc73c\uba74 Dispatchers.Default\uac00 \uc9c0\uc815\ub41c\ub2e4.<\/p>\n\n\n\n<p>\uae30\ubcf8\uc801\uc73c\ub85c \ucf54\ub8e8\ud2f4\uc740 \uc989\uc2dc \uc2e4\ud589\ub418\ub3c4\ub85d \uc2a4\ucf00\uc974\ub9c1\ub41c\ub2e4. \ub2e4\ub978 \uc2dc\uc791 \uc635\uc158\uc740 start \ub9e4\uac1c\ubcc0\uc218\ub97c \ud1b5\ud574 \uc9c0\uc815\ud560 \uc218 \uc788\uc73c\uba70, \uc120\ud0dd\uc801\uc73c\ub85c CoroutineStart.Lazy\ub85c \uc124\uc815\ud558\uc5ec \ucf54\ub8e8\ud2f4\uc744 \ub290\ub9ac\uac8c \uc2dc\uc791\ud560 \uc218 \uc788\ub2e4. \uc774 \uacbd\uc6b0 \ucf54\ub8e8\ud2f4 Job\uc740 \uc0c8\ub85c\uc6b4 \uc0c1\ud0dc\ub85c \uc0dd\uc131\ub41c\ub2e4. start\uc758 \uae30\ubcf8\uac12\uc740 CoroutineStart.DEFAULT \ub2e4.<\/p>\n\n\n\n<p>\uc774 \ucf54\ub8e8\ud2f4\uc758 catch \ub418\uc9c0 \uc54a\uc740 \uc608\uc678\ub4e4\uc740 \uae30\ubcf8\uc801\uc73c\ub85c \ud574\ub2f9 \ucee8\ud14d\uc2a4\ud2b8\uc758 \uc0c1\uc704 \uc791\uc5c5\uc744 \ucde8\uc18c\ud55c\ub2e4. \uc774\ub294 launch\uac00 \ub2e4\ub978 \ucf54\ub8e8\ud2f4\uc758 \ucee8\ud14d\uc2a4\ud2b8\uc640 \ud568\uaed8 \uc0ac\uc6a9 \ub420 \ub54c \ud3ec\ucc29\ub418\uc9c0 \uc54a\uc740 \uc608\uc678\uac00 \uc0c1\uc704 \ucf54\ub8e8\ud2f4\uc758 \ucde8\uc18c\ub85c \uc774\uc5b4\uc9c4\ub2e4\ub294 \uac83\uc744 \uc758\ubbf8 \ud55c\ub2e4. <\/p>\n\n\n\n<p><strong>runBlocking builder<\/strong><\/p>\n\n\n\n<p>\uc0c8 \ucf54\ub8e8\ud2f4\uc744 \uc2e4\ud589\ud558\uace0 \uc644\ub8cc\ub420 \ub54c\uae4c\uc9c0 \ud604\uc7ac \uc0ac\uc6a9\ud558\uace0 \uc788\ub294 \uc2a4\ub808\ub4dc\uc758 \uc778\ud130\ub7fd\ud2b8\ub97c \ucc28\ub2e8\ud55c\ub2e4. \uc774 \ud568\uc218\ub294 \ucf54\ub8e8\ud2f4\uc5d0\uc11c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \uac83\uc774 \uc88b\ub2e4. \uc774 \ud568\uc218\ub294 \ub2e8\uc9c0 main \ud568\uc218\ub098 \ud14c\uc2a4\ud2b8\uc5d0\uc11c \uc0ac\uc6a9\ub418\uae30 \uc704\ud574 \uc124\uacc4\ub418\uc5c8\uae30 \ub54c\ubb38\uc774\ub2e4. <\/p>\n\n\n\n<p>\uc774 \ucf54\ub8e8\ud2f4 \ube4c\ub354\uc758 \uae30\ubcf8\uc801\uc778 CoroutineDispatcher\ub294 \uc774 \ucf54\ub8e8\ud2f4\uc774 \uc644\ub8cc\ub420 \ub54c\uae4c\uc9c0 \ucc28\ub2e8\ub41c \uc2a4\ub808\ub4dc\uc5d0\uc11c Continuation\uc744 \ucc98\ub9ac\ud558\ub294 \ub0b4\ubd80 \uc774\ubca4\ud2b8 \ub8e8\ud504\uc758 \uad6c\ud604\uc774\ub2e4. <\/p>\n\n\n\n<p>CoroutineDispatcher\uac00 \ucee8\ud14d\uc2a4\ud2b8\uc5d0\uc11c \uba85\uc2dc\uc801\uc73c\ub85c \uc9c0\uc815\ub418\uba74 \uc0c8 \ucf54\ub8e8\ud2f4\uc740 \ud604\uc7ac \uc2a4\ub808\ub4dc\uac00 \ucc28\ub2e8\ub418\ub294 \ub3d9\uc548 \uc9c0\uc815\ub41c \ub514\uc2a4\ud328\ucc98\uc758 \ucee8\ud14d\uc2a4\ud2b8\uc5d0\uc11c \uc2e4\ud589\ub41c\ub2e4. \uc774 \ucc28\ub2e8\ub41c \uc2a4\ub808\ub4dc\uac00 \uc778\ud130\ub7fd\ud2b8 \ub418\uba74 \ucf54\ub8e8\ud2f4 job\uc774 \ucde8\uc18c\ub418\uace0 interruptedException\uc774 \ubc1c\uc0dd\ud55c\ub2e4.<\/p>\n\n\n\n<p><strong>async builder<\/strong><\/p>\n\n\n\n<p>\ucf54\ub8e8\ud2f4\uc744 \ub9cc\ub4e4\uace0 Deffered\uc758 \uad6c\ud604\uc73c\ub85c \ud574\ub2f9 \uacb0\uacfc\ub97c \ubc18\ud658\ud55c\ub2e4. \uc2e4\ud589 \uc911\uc778 \ucf54\ub8e8\ud2f4\uc740 deferred\uc758 \uacb0\uacfc\uac00 \ucde8\uc18c\ub418\uba74 \ucde8\uc18c\ub41c\ub2e4. \uacb0\uacfc \ucf54\ub8e8\ud2f4\uc740 \ub2e4\ub978 \uc5b8\uc5b4 \ubc0f \ud504\ub808\uc784\uc6cc\ud06c\uc758 \uc720\uc0ac\ud55c \uae30\ucd08 \uc694\uc18c\uc640 \ube44\uad50\ud558\uc5ec \uc911\uc694\ud55c \ucc28\uc774\uc810\uc774 \uc788\ub2e4. \uad6c\uc870\ud654 \ub41c \ub3d9\uc2dc\uc131 \ud328\ub7ec\ub2e4\uc784\uc744 \uc2dc\ud589\ud558\uc9c0 \ubabb\ud558\uba74 \uc0c1\uc704 \uc791\uc5c5\uc744 \ucde8\uc18c\ud55c\ub2e4. \ud574\ub2f9 \ub3d9\uc791\uc744 \ubcc0\uacbd\ud558\ub824\uba74 SupervisorJob \ub610\ub294 supervisorScope\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4. <\/p>\n\n\n\n<p>\ucf54\ub8e8\ud2f4 \ucee8\ud14d\uc2a4\ud2b8\ub294 CoroutineScope\uc5d0\uc11c \uc0c1\uc18d\ub418\uba70 context \uc778\uc790\uc640 \ud568\uaed8 \ucd94\uac00\uc801\uc778 \ucee8\ud14d\uc2a4\ud2b8\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4.  \ucee8\ud14d\uc2a4\ud2b8\uc5d0 dispatcher\ub098 \ub2e4\ub978 ContinuationInterceptor\uac00 \uc5c6\uc73c\uba74 Dispatchers.Default\uac00 \uc0ac\uc6a9\ub41c\ub2e4. \ubd80\ubaa8 \uc791\uc5c5\ub3c4 CoroutineScope\uc5d0\uc11c \uc0c1\uc18d\ub418\uc9c0\ub9cc \ud574\ub2f9 \ucee8\ud14d\uc2a4\ud2b8 \uc694\uc18c\ub85c \uc624\ubc84\ub77c\uc774\ub4dc \ub420 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<p>launch\uc640 \ub9c8\ucc2c\uac00\uc9c0\ub85c \uae30\ubcf8\uc801\uc73c\ub85c \ucf54\ub8e8\ud2f4\uc740 \uc989\uc2dc \uc2e4\ud589\ub418\ub3c4\ub85d \uc2a4\ucf00\uc974\ub9c1\ub418\uba70, \uc2dc\uc791\uc635\uc158\uc744 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\ucde8\uc18c \ubc0f \ud0c0\uc784\uc544\uc6c3<\/h3>\n\n\n\n<p>launch \ud568\uc218\uc758 \ubc18\ud658\uc73c\ub85c \uc5bb\uc740 Job\uc5d0 \ub300\ud574 cancel() \ud568\uc218\ub97c \ud638\ucd9c\ud558\uc5ec \ucde8\uc18c\ub97c \ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>fun main() = runBlocking {\n    val job1 = launch {\n        delay(1000L)\n        println(\"1\")\n    }\n\n    val job2 = launch { println(\"2\") }\n    val job3 = launch { println(\"3\") }\n    \n    delay(500L)\n    <strong>job1.cancel()\n    job2.cancel()<\/strong>\n}\n\/\/\uc2e4\ud589 \uacb0\uacfc\n\/\/ 2\n\/\/ 3<\/code><\/pre>\n\n\n\n<p>\ucf54\ub8e8\ud2f4 \ub0b4\ubd80\uc5d0\uc11c \uc791\uc5c5\uc774 \ucde8\uc18c \ub418\uc5c8\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ubc29\ubc95\uc740 isActive \ud50c\ub798\uadf8\ub97c \ud65c\uc6a9\ud558\ub294 \uac83\uc774\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>val startTime = System.currentTimeMillis()\nval job = launch(Dispatchers.Default) {\n    var nextPrintTime = startTime\n    while (<strong>isActive<\/strong>) { \/\/ \b\ucde8\uc18c \uc5ec\ubd80 \ud655\uc778\n        if (System.currentTimeMillis() >= nextPrintTime) {\n            println(\"job: I'm sleeping ${i++} ...\")\n            nextPrintTime += 500L\n        }\n    }\n}\ndelay(1300L) \/\/ \uc791\uc5c5\uc774 \ub05d\ub0a0 \ub54c \uae4c\uc9c0 \uc870\uae08 \uae30\ub2e4\ub9bc\nprintln(\"main: I'm tired of waiting!\")\n<strong>job.cancelAndJoin()<\/strong> \/\/ \uc791\uc5c5\uc744 \ucde8\uc18c\ud558\uace0 \uc644\ub8cc\ub420 \ub54c\uae4c\uc9c0 \uae30\ub2e4\ub9b0\ub2e4.\nprintln(\"main: Now I can quit.\")\n\n\/\/ \uc2e4\ud589\uacb0\uacfc \n\/\/ job: I'm sleeping 0 ...\n\/\/ job: I'm sleeping 1 ...\n\/\/ job: I'm sleeping 2 ...\n\/\/ main: I'm tired of waiting!\n\/\/ main: Now I can quit.<\/code><\/pre>\n\n\n\n<p>suspend \ud568\uc218\ub4e4\uc740 <strong>JobCancellationException<\/strong>\uc774 \ubc1c\uc0dd\ud558\uae30 \ub54c\ubb38\uc5d0 \uc774\ub97c try catch \ube14\ub85d\uc73c\ub85c \uc608\uc678\ucc98\ub9ac \ud558\ub294 \ubc29\ubc95\ub3c4 \uc788\ub2e4.<\/p>\n\n\n\n<p>\uc5b4\ub5a4 \ucf54\ub4dc\ub4e4\uc740 \ucde8\uc18c\uac00 \ubd88\uac00\ud574\uc57c\ud55c\ub2e4. \uadf8\ub7f4 \ub54c\ub294 <strong>withContext(NonCancellable)<\/strong>\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>fun main() = runBlocking {\n    val job1 = launch {\n        <strong>withContext(NonCancellable)<\/strong> {\n            delay(1000)\n            println(\"I survived!\")\n        }\n        delay(1000)\n        print(\"job1: end\")\n    }\n\n    delay(500L)\n    <strong>job1.cancel()<\/strong>\n}\n\n\/\/ \uc2e4\ud589\uacb0\uacfc\n\/\/ I survived!<\/code><\/pre>\n\n\n\n<p>\uc77c\uc815 \uc2dc\uac04\uc774 \uc9c0\ub09c \ub2e4\uc74c \uc885\ub8cc\ud558\uace0 \uc2f6\ub2e4\uba74 withTimeout\uc744 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>suspend fun doCount() = coroutineScope {\n    val job1 = launch(Dispatchers.Default) {\n        var i = 1\n        var nextTime = System.currentTimeMillis() + 100L\n\n        while (i &lt;= 10 &amp;&amp; isActive) {\n            val currentTime = System.currentTimeMillis()\n            if (currentTime >= nextTime) {\n                println(i)\n                nextTime = currentTime + 100L\n                i++\n            }\n        }\n    }\n}\n\nfun main() = runBlocking {\n    <strong>withTimeout(500L)<\/strong> {\n        doCount()\n    }\n}\n\n\/\/ \uc2e4\ud589\uacb0\uacfc\n\/\/ 1\n\/\/ 2\n\/\/ 3\n\/\/ 4\n\/\/ Exception in thread \"main\" kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 500 ms<\/code><\/pre>\n\n\n\n<p>\ucde8\uc18c\uac00 \ub418\uba74\u00a0<code>TimeoutCancellationException<\/code>\u00a0\uc608\uc678\uac00 \ubc1c\uc0dd\ud55c\ub2e4. \ub9cc\uc57d \uc5d0\ub7ec \ud578\ub4e4\ub9c1\ud558\ub294\uac8c \uadc0\ucc2e\uace0 null\uc744 \ubc18\ud658\ud558\uc5ec \uc774\ub97c \ucc98\ub9ac\ud558\uace0 \uc2f6\ub2e4\uba74 <strong>withTimeoutOrNull<\/strong>\uc744 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\bCoroutineExceptionHandler \ubc0f SupervisorJob<\/h3>\n\n\n\n<p>\uc608\uc678\ub97c \uac00\uc7a5 \uccb4\uacc4\uc801\uc73c\ub85c \ub2e4\ub8e8\ub294 \ubc29\ubc95\uc740 CEH (Coroutine Exception Handler, \ucf54\ub8e8\ud2f4 \uc775\uc149\uc158 \ud578\ub4e4\ub7ec)\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc774\ub2e4. \ucee4\uc2a4\ud140 CEH\ub97c \ub9cc\ub4e0 \ub2e4\uc74c \uc0c1\uc704 \ucf54\ub8e8\ud2f4 \ube4c\ub354\uc758 \ucee8\ud14d\uc2a4\ud2b8\uc5d0 \ub4f1\ub85d\ud558\uba74 \ud558\uc704\uc758 \ubaa8\ub4e0 \uc608\uc678\uae4c\uc9c0 \uc885\ud569\uc801\uc73c\ub85c \ud578\ub4e4\ub9c1 \uac00\ub2a5\ud558\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>val ceh = CoroutineExceptionHandler { coroutineContext, exception ->\n    println(\"\uc5d0\ub7ec \ub0b4\uc6a9: $exception\")\n}\n\nfun main() = runBlocking&lt;Unit> {\n    val scope = CoroutineScope(Dispatchers.IO)\n    val job = scope.launch (<strong>ceh<\/strong>) {\n        launch { \n            <meta charset=\"utf-8\">delay(1000L)\n            println(\"Hello World\") \/\/ \uc5d0\ub7ec \ub54c\ubb38\uc5d0 \uc2e4\ud589\ub418\uc9c0 \uc54a\uc74c\n        }\n        launch { \n            delay(500L)\n            throw Exception() \/\/ \uc5d0\ub7ec \ubc1c\uc0dd\n        }\n    }\n    job.join()\n}\n\n\/\/ \uc2e4\ud589 \uacb0\uacfc\n\/\/ \uc5d0\ub7ec \ub0b4\uc6a9: java.lang.Exception<\/code><\/pre>\n\n\n\n<p>\ucc38\uace0\ub85c runBlocking\uc5d0\uc11c\ub294 CEH\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc5c6\ub2e4. runBlocking\uc740 \uc790\uc2dd\uc774 \uc608\uc678\ubc1c\uc0dd\uc73c\ub85c \uc778\ud574 \uc885\ub8cc\ub418\uba74 \uadf8\ub0e5  \uc885\ub8cc\ub41c\ub2e4.<\/p>\n\n\n\n<p>SupervisorJob\uc740 \uc608\uc678\uc5d0 \uc758\ud55c \ucde8\uc18c\ub97c \ud558\uc704 \ucf54\ub8e8\ud2f4\uc73c\ub85c \uc804\ud30c\ud55c\ub2e4. \uc704\uc758 \uc608\uc81c\uc640 \ube44\uc2b7\ud55c \ub0b4\uc6a9\uc744 SupervisorJob\uc744 \uc0ac\uc6a9\ud558\uc5ec \ub2e4\uc74c\uacfc \uac19\uc774 \uc2e4\ud589\ud574\ubcf4\uc790.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong>val ceh = CoroutineExceptionHandler<\/strong> { coroutineContext, exception ->\n    println(\"\uc5d0\ub7ec \ub0b4\uc6a9: $exception\")\n}\n\nfun main() = runBlocking&lt;Unit> {\n    val scope = CoroutineScope(Dispatchers.IO+<strong>ceh<\/strong>+<strong>SupervisorJob()<\/strong>)\n    val job1 = scope.launch {\n        delay(1000L)\n        println(\"Hello World\") \/\/ \uc5d0\ub7ec\uac00 \ubc1c\uc0dd\ud574\ub3c4 \uc2e4\ud589\ub428\n    }\n    val job2 = scope.launch {\n        delay(500L)\n        throw Exception() \n    }\n    joinAll(job1, job2)\n}\n\n\/\/ \uc2e4\ud589 \uacb0\uacfc\n\/\/ \uc5d0\ub7ec \ub0b4\uc6a9: java.lang.Exception\n\/\/ Hello World<\/code><\/pre>\n\n\n\n<p>CoroutineScope\uc640 SupervisorJob\uc744 \ud569\uce5c\ub4ef \ud55c SupervisorScope\uac00 \uc788\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>val ceh = CoroutineExceptionHandler { coroutineContext, exception ->\n    println(\"\uc5d0\ub7ec \ub0b4\uc6a9: $exception\")\n}\n\nfun main() = runBlocking&lt;Unit> {\n\tval scope = CoroutineScope(ceh)\n    val job = scope.launch{\n        <strong>supervisorScope<\/strong> {\n            launch {\n                delay(1000L)\n                println(\"Hello World\") \n            }\n            launch {\n                delay(500L)\n                throw Exception() \n            }\n        }\n    }\n    job.join()\n}\n\/\/ \uc2e4\ud589\uacb0\uacfc \n\/\/ \uc5d0\ub7ec \ub0b4\uc6a9: java.lang.Exception\n\/\/ Hello World<\/code><\/pre>\n\n\n\n<p>supervisorScope\ub97c \uc0ac\uc6a9\ud560 \ub54c \uc8fc\uc758\ud560 \uc810\uc740 \ubb34\uc870\uac74 \uc790\uc2dd \uc218\uc900\uc5d0\uc11c \uc608\uc678\ub97c \ud578\ub4e4\ub9c1 \ud574\uc57c\ud55c\ub2e4\ub294 \uac83\uc774\ub2e4. \uc790\uc2dd\uc758 \uc2e4\ud328\uac00 \ubd80\ubaa8\uc5d0\uac8c \uc804\ub2ec\ub418\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0 \uc790\uc2dd \uc218\uc900\uc5d0\uc11c \uc608\uc678\ub97c \ucc98\ub9ac\ud574\uc57c \ud558\ub294 \uac83\uc744 \uba85\uc2ec\ud558\uc790.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">actor<\/h3>\n\n\n\n<p>\uc561\ud130\ub294 1973\ub144\uc5d0 \uce7c \ud734\uc774\ud2b8\uac00 \ub9cc\ub4e0 \uac1c\ub150\uc73c\ub85c \uc561\ud130\uac00 \ub3c5\uc810\uc801\uc73c\ub85c \uc790\ub8cc\ub97c \uac16\uace0, \uadf8 \uc790\ub8cc\ub97c \ub2e4\ub978 \ucf54\ub8e8\ud2f4\uacfc \uacf5\uc720\ud558\uc9c0 \uc54a\uace0 \uc561\ud130\ub97c \ud1b5\ud574\uc11c\ub9cc \uc811\uadfc\ud558\uac8c \ub9cc\ub4e0\ub2e4. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sealed class CounterMsg\nobject IncCounter : CounterMsg()\nclass GetCounter(val response: CompletableDeferred&lt;Int>) : CounterMsg()\n\nfun main() = runBlocking&lt;Unit> {\n    val counter = counterActor() \/\/ CounterMsg\ub9cc \ub2e4\ub8e8\ub294 \uc561\ud130 \uc0dd\uc131\n    withContext(Dispatchers.Default) {\n        massiveRun { \/\/ IntCounter\ub97c 100*1000 (10\ub9cc\ubc88) \uc804\uc1a1\n            counter.send(IncCounter) \n        }\n    }\n\n    val response = CompletableDeferred&lt;Int>() \/\/ \uacb0\uacfc\ub97c \uc804\ub2ec \ubc1b\uae30 \uc704\ud55c CompletableDeffered\n    counter.send(GetCounter(response)) \/\/ response\ub97c \uc804\ub2ec\ud558\uace0,\n    println(\"Counter = ${response.await()}\") \/\/ await()\ud558\uba74 \uacb0\uacfc\ub97c \ubc18\ud658\ud574\uc900\ub2e4.     \n    counter.close()\n}\n\n\/\/ \ub300\ub7c9 \uc2e4\ud589 \uc791\uc5c5 (10\ub9cc\ubc88 \ubc18\ubcf5)\nsuspend fun massiveRun(action: suspend () -> Unit) {\n    val n = 100\n    val k = 1000\n    val elapsed = measureTimeMillis {\n        coroutineScope {\n            repeat(n) {\n                launch {\n                    repeat(k) { action() }\n                }\n            }\n        }\n    }\n    println(\"$elapsed ms\ub3d9\uc548 ${n * k}\uac1c\uc758 \uc561\uc158\uc744 \uc218\ud589\ud588\uc2b5\ub2c8\ub2e4.\")  \n}\n\n\/\/ ConterMsg\ub9cc \ub2e4\ub8e8\ub294 \uc561\ud130\nfun CoroutineScope.counterActor() = <strong>actor<\/strong>&lt;CounterMsg> {\n    var counter = 0\n    for (msg in channel) {\n        when (msg) {\n            is IncCounter -> counter++\n            is GetCounter -> msg.response.complete(counter)\n        }\n    }\n}\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\ucf54\ub8e8\ud2f4(Coroutines)\uc774\ub780? \ucf54\ub8e8\ud2f4\uc740 \ube44\ub3d9\uae30\uc801\uc73c\ub85c \uc2e4\ud589\ub418\ub294 \ucf54\ub4dc\ub97c \uac04\uc18c\ud654\ud558\uae30 \uc704\ud574 Android\uc5d0\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \ub3d9\uc2dc \uc2e4\ud589 \uc124\uacc4 \ud328\ud134\uc774\ub2e4. \ucf54\ub8e8\ud2f4\uc740 \ub2e4\uc74c\uacfc \uac19\uc740 \ud2b9\uc9d5\uc744 \uac16\ub294\ub2e4. \uacbd\ub7c9\ud654 \uba54\ubaa8\ub9ac \ub204\uc218 \uac10\uc18c \uacc4\uce35\uc801 \uad6c\uc870\ub97c \ud1b5\ud55c \ucde8\uc18c \uc804\ub2ec Jetpack\uacfc\uc758 \ud1b5\ud569 Suspend function suspend(\uc720\uc608\ud558\ub2e4, \uc5f0\uae30\ud558\ub2e4) vs block(\ub9c9\ub2e4, \ucc28\ub2e8\ud558\ub2e4) blocking\uacfc suspending\uc758 \ucc28\uc774\uc5d0 \ub300\ud574\uc11c \uba3c\uc800 \uc54c\uc544\ubcf4\uc790. \ub2e8\uc77c \uc4f0\ub808\ub4dc\uc5d0\uc11c \ub124\ud2b8\uc6cc\ud06c \uc694\uccad(FUNCTION A)\uacfc \uac19\uc740 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"inline_featured_image":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[5],"tags":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/45962"}],"collection":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=45962"}],"version-history":[{"count":1,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/45962\/revisions"}],"predecessor-version":[{"id":45970,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/45962\/revisions\/45970"}],"wp:attachment":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=45962"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=45962"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=45962"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}