{"id":243,"date":"2024-04-22T02:16:04","date_gmt":"2024-04-21T17:16:04","guid":{"rendered":"https:\/\/redutan.synology.me\/wordpress\/?p=243"},"modified":"2024-04-23T18:40:04","modified_gmt":"2024-04-23T09:40:04","slug":"java-21-virtual-thread-configuration-on-spring-boot-3-2-x","status":"publish","type":"post","link":"https:\/\/redutan.synology.me\/wordpress\/2024\/04\/22\/java-21-virtual-thread-configuration-on-spring-boot-3-2-x\/","title":{"rendered":"Java 21 Virtual Thread Configuration on spring-boot 3.2.x"},"content":{"rendered":"\n<blockquote class=\"wp-block-quote\">\n<p>\uc774 \uae00\uc744 \uc77d\uae30 \uc804\uc5d0 \uc544\ub798 \uae00\uc744 \uba3c\uc800 \uc77d\uae30\ub97c \ucd94\ucc9c\ub4dc\ub9bd\ub2c8\ub2e4. \uba3c\uc800 Virtual Thread\ub97c \uc801\uc6a9\ud558\uae30 \uc804\uc5d0 \uc81c\uc57d\uc5d0 \ub300\ud55c \uc774\ud574\uac00 \ud544\uc694\ud569\ub2c8\ub2e4.<\/p>\n<cite><a href=\"https:\/\/redutan.synology.me\/wordpress\/2024\/04\/22\/virtual-thread-pinning-issue%ec%9e%91%ec%84%b1-%ec%a4%91\/\" title=\"\">\bISSUE: Pinning inside synchronized<\/a><\/cite><\/blockquote>\n\n\n\n<p>spring-boot 3.2.x \uc5d0\uc11c \ub4dc\ub514\uc5b4 <a href=\"https:\/\/openjdk.org\/jeps\/444\" target=\"_blank\" rel=\"noopener\" title=\"\">JEP-444<\/a> Virtual Thread \uae30\ub2a5\uc744 \ud65c\uc131\ud654 \uc2dc\ud0ac \uc218 \uc788\uc2b5\ub2c8\ub2e4.<br>Virtual Thread \uc640 \uad00\ub828\ub41c \uc790\uc138\ud55c \ub0b4\uc6a9\uc744 \uc54c\uace0 \uc2f6\uc73c\uc2dc\uba74, <a href=\"https:\/\/docs.oracle.com\/en\/java\/javase\/21\/core\/virtual-threads.html\" target=\"_blank\" rel=\"noopener\" title=\"\">Oracle \uacf5\uc2dd \ubb38\uc11c<\/a>\ub97c \ud655\uc778\ud558\ub294 \uac83\uc744 \ucd94\ucc9c\ud569\ub2c8\ub2e4.<br>(\uae30\uc874 Thread\ub294 Platform Thread\ub77c\uace0 \ubd80\ub974\ub124\uc694.)<\/p>\n\n\n\n<blockquote class=\"wp-block-quote\">\n<p>\uacb0\ub860 \ubd80\ud130 \ub9d0\uc500\ub4dc\ub9ac\uba74 \uc11c\ube44\uc2a4\uac00 DB(jdbc-drivere)\uc5d0 \uc758\uc874\ud558\uace0 \uc788\ub2e4\uba74 \uc544\uc9c1\uc740 Virtual Thread\ub97c \uc0ac\uc6a9\ud558\uae30\uc5d0\ub294 \ubb34\ub9ac\uc785\ub2c8\ub2e4. <\/p>\n<cite>\uae30\ubcf8 \uc804\ub7b5\uc73c\ub85c\ub294 Platform Thread(\uae30\uc874 \ubc29\uc2dd)\uc744 \uadf8\ub300\ub85c \uc0ac\uc6a9\ud558\uc2dc\uace0, I\/O \ub300\uae30\uac00 \uac78\ub9ac\ub294 \ubd80\ubd84\ub9cc Virtual Thread\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc744 \uad8c\uc7a5\ud569\ub2c8\ub2e4.<\/cite><\/blockquote>\n\n\n\n<p><\/p>\n\n\n\n<h2>Virtual Thread<\/h2>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282A36\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"spring:\n  threads:\n    virtual:\n      enabled: true                   # virtual thread \ud65c\uc131\ud654\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki dracula\" style=\"background-color: #282A36\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #8BE9FD\">spring<\/span><span style=\"color: #FF79C6\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  <\/span><span style=\"color: #8BE9FD\">threads<\/span><span style=\"color: #FF79C6\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #8BE9FD\">virtual<\/span><span style=\"color: #FF79C6\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #8BE9FD\">enabled<\/span><span style=\"color: #FF79C6\">:<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #BD93F9\">true<\/span><span style=\"color: #F8F8F2\">                   <\/span><span style=\"color: #6272A4\"># virtual thread \ud65c\uc131\ud654<\/span><\/span><\/code><\/pre><span style=\"display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#282A36;color:#efefe1;font-size:12px;line-height:1;position:relative\">YAML<\/span><\/div>\n\n\n\n<p>\uc704 \uc635\uc158\uc73c\ub85c \ud65c\uc131\ud654 \uc2dc\ud0a4\uba74 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ub0b4 \ubaa8\ub4e0 Thread \ub4e4\uc774 Virtual thread\ub85c \ud65c\uc131\ud654 \ub429\ub2c8\ub2e4. Tomcat \uc6f9\uc11c\ubc84, Async, Scheduling \ub4f1 \ub2e4 \ud3ec\ud568\ub429\ub2c8\ub2e4. \uae30\uc874\uc5d0 Platform Thread\ub97c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0\uc5d0\ub294 Thread \uc0dd\uc131 \ube44\uc6a9\uc774 \ube44\uc2f8\uae30 \ub54c\ubb38\uc5d0 \uae30\ubcf8\uc801\uc73c\ub85c Thread Pool \ub85c \uc124\uc815\ud574\uc57c\ud569\ub2c8\ub2e4. \ud558\uc9c0\ub9cc Virtual Thread\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uba74 Thread Pool \uc124\uc815\uc740 \uc624\ud788\ub824 \ub0ad\ube44\uac00 \ub429\ub2c8\ub2e4. \uadf8\ub7ec\ubbc0\ub85c Thread Pool \uc124\uc815\uc744 \ube44\ud65c\uc131\ud654 \ud574\uc57c\ud569\ub2c8\ub2e4. \ud639\uc2dc\ub098 \ucee4\uc2a4\ud140\uc73c\ub85c \uc124\uc815\ub41c \uac83\uc774 \uc788\ub2e4\uba74 \uc81c\uac70\ud574\uc57c\ud569\ub2c8\ub2e4.<\/p>\n\n\n\n<p><em><code>TomcatWebServerFactoryCustomizer<\/code> \ucf54\ub4dc \uc77c\ubd80<\/em><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282A36\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\t@Configuration(proxyBeanMethods = false)\n\t@ConditionalOnClass({ Tomcat.class, UpgradeProtocol.class })\n\tpublic static class TomcatWebServerFactoryCustomizerConfiguration {\n\n\t\t@Bean\n\t\tpublic TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(Environment environment,\n\t\t\t\tServerProperties serverProperties) {\n\t\t\treturn new TomcatWebServerFactoryCustomizer(environment, serverProperties);\n\t\t}\n\n\t\t@Bean\n\t\t@ConditionalOnThreading(Threading.VIRTUAL)\n\t\tTomcatVirtualThreadsWebServerFactoryCustomizer tomcatVirtualThreadsProtocolHandlerCustomizer() {\n\t\t\treturn new TomcatVirtualThreadsWebServerFactoryCustomizer();\n\t\t}\n\t}\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki dracula\" style=\"background-color: #282A36\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F8F8F2\">\t@<\/span><span style=\"color: #8BE9FD; font-style: italic\">Configuration<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #BD93F9\">proxyBeanMethods<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #FF79C6\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #BD93F9\">false<\/span><span style=\"color: #F8F8F2\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t@<\/span><span style=\"color: #8BE9FD; font-style: italic\">ConditionalOnClass<\/span><span style=\"color: #F8F8F2\">({ Tomcat.class, UpgradeProtocol.class })<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t<\/span><span style=\"color: #FF79C6\">public<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #FF79C6\">static<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #FF79C6\">class<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #8BE9FD\">TomcatWebServerFactoryCustomizerConfiguration<\/span><span style=\"color: #F8F8F2\"> {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t@<\/span><span style=\"color: #8BE9FD; font-style: italic\">Bean<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t<\/span><span style=\"color: #FF79C6\">public<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #8BE9FD; font-style: italic\">TomcatWebServerFactoryCustomizer<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #50FA7B\">tomcatWebServerFactoryCustomizer<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #8BE9FD; font-style: italic\">Environment<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #FFB86C; font-style: italic\">environment<\/span><span style=\"color: #F8F8F2\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t\t<\/span><span style=\"color: #8BE9FD; font-style: italic\">ServerProperties<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #FFB86C; font-style: italic\">serverProperties<\/span><span style=\"color: #F8F8F2\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t<\/span><span style=\"color: #FF79C6\">return<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #FF79C6; font-weight: bold\">new<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #50FA7B\">TomcatWebServerFactoryCustomizer<\/span><span style=\"color: #F8F8F2\">(environment, serverProperties);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t@<\/span><span style=\"color: #8BE9FD; font-style: italic\">Bean<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t@<\/span><span style=\"color: #8BE9FD; font-style: italic\">ConditionalOnThreading<\/span><span style=\"color: #F8F8F2\">(Threading.VIRTUAL)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t<\/span><span style=\"color: #8BE9FD; font-style: italic\">TomcatVirtualThreadsWebServerFactoryCustomizer<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #50FA7B\">tomcatVirtualThreadsProtocolHandlerCustomizer<\/span><span style=\"color: #F8F8F2\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t<\/span><span style=\"color: #FF79C6\">return<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #FF79C6; font-weight: bold\">new<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #50FA7B\">TomcatVirtualThreadsWebServerFactoryCustomizer<\/span><span style=\"color: #F8F8F2\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t}<\/span><\/span><\/code><\/pre><span style=\"display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#282A36;color:#efefe1;font-size:12px;line-height:1;position:relative\">Java<\/span><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2>Async<\/h2>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282A36\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"spring:\n  task:\n    execution:\n      shutdown:\n        await-termination: true       # \uc2a4\ub808\ub4dc\uac00 \uc885\ub8cc\ub420 \ub54c \uae4c\uc9c0 \ub300\uae30\ud560 \uac83\uc778\uac00?\n        await-termination-period: 30s # \uc885\ub8cc \uc2dc \ucd5c\ub300 \ub300\uae30 \uae30\uac04\n      simple:\n        concurrency-limit: -1         # -1: unllimited\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki dracula\" style=\"background-color: #282A36\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #8BE9FD\">spring<\/span><span style=\"color: #FF79C6\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  <\/span><span style=\"color: #8BE9FD\">task<\/span><span style=\"color: #FF79C6\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #8BE9FD\">execution<\/span><span style=\"color: #FF79C6\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #8BE9FD\">shutdown<\/span><span style=\"color: #FF79C6\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        <\/span><span style=\"color: #8BE9FD\">await-termination<\/span><span style=\"color: #FF79C6\">:<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #BD93F9\">true<\/span><span style=\"color: #F8F8F2\">       <\/span><span style=\"color: #6272A4\"># \uc2a4\ub808\ub4dc\uac00 \uc885\ub8cc\ub420 \ub54c \uae4c\uc9c0 \ub300\uae30\ud560 \uac83\uc778\uac00?<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        <\/span><span style=\"color: #8BE9FD\">await-termination-period<\/span><span style=\"color: #FF79C6\">:<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #F1FA8C\">30s<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #6272A4\"># \uc885\ub8cc \uc2dc \ucd5c\ub300 \ub300\uae30 \uae30\uac04<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #8BE9FD\">simple<\/span><span style=\"color: #FF79C6\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        <\/span><span style=\"color: #8BE9FD\">concurrency-limit<\/span><span style=\"color: #FF79C6\">:<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #BD93F9\">-1<\/span><span style=\"color: #F8F8F2\">         <\/span><span style=\"color: #6272A4\"># -1: unllimited<\/span><\/span><\/code><\/pre><span style=\"display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#282A36;color:#efefe1;font-size:12px;line-height:1;position:relative\">YAML<\/span><\/div>\n\n\n\n<p>Schedulinng \uad00\ub828 \uc124\uc815\uc740 \uc5c6\uc2b5\ub2c8\ub2e4.<br><br>Virtual Thread\ub97c \ud65c\uc131\ud654 \uc2dc\ud0a4\uba74 spring task(<code>@Async<\/code>) \uc5d0\uc11c\ub294 \uae30\ubcf8\uc801\uc73c\ub85c <code>SimpleAsyncTaskExecutor<\/code>\ub97c \uc0ac\uc6a9\ud558\uac8c \ub429\ub2c8\ub2e4. \uace0\ub85c \ud544\uc694\ud55c \uc124\uc815\uc740 \uc544\ub798 4\uac1c\uc758 \uc18d\uc131\ub9cc \uc124\uc815\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<ul>\n<li><code>spring.task.execution.thread-name-prefix<\/code><\/li>\n\n\n\n<li><code>spring.task.execution.simple.concurrency-limit<\/code><\/li>\n\n\n\n<li><code>spring.task.execution.shutdown.await-termination<\/code><\/li>\n\n\n\n<li><code><code>spring.task.execution.shutdown.await-termination<\/code><\/code>-period<\/li>\n<\/ul>\n\n\n\n<p>\uc800\ub294 \uadf8 \uc911\uc5d0\uc11c <code>spring.task.execution.thread-name-prefix<\/code> \ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<p>\uc774 \ub0b4\uc6a9\uc740 spring-boot \ubb38\uc11c\uc5d0\ub3c4 \uadf8\ub807\uac8c \uc801\ud600\uc838 \uc788\uc73c\uba70, \uc2e4\uc81c \ucf54\ub4dc\ub97c \ud655\uc778\ud574\ub3c4 \uadf8\ub807\uc2b5\ub2c8\ub2e4. \uc544\ub798 \ucf54\ub4dc\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282A36\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"  @Bean(\n      name = {&quot;simpleAsyncTaskExecutorBuilder&quot;}\n  )\n  @ConditionalOnMissingBean\n  @ConditionalOnThreading(Threading.VIRTUAL)\n  SimpleAsyncTaskExecutorBuilder simpleAsyncTaskExecutorBuilderVirtualThreads() {\n      SimpleAsyncTaskExecutorBuilder builder = this.builder();\n      builder = builder.virtualThreads(true);\n      return builder;\n  }\n\n  private SimpleAsyncTaskExecutorBuilder builder() {\n      SimpleAsyncTaskExecutorBuilder builder = new SimpleAsyncTaskExecutorBuilder();\n      \/\/ spring.task.execution.thread-name-prefix\n      builder = builder.threadNamePrefix(this.properties.getThreadNamePrefix());\n      Stream var10001 = this.taskExecutorCustomizers.orderedStream();\n      Objects.requireNonNull(var10001);\n      builder = builder.customizers(var10001::iterator);\n      builder = builder.taskDecorator((TaskDecorator)this.taskDecorator.getIfUnique());\n      TaskExecutionProperties.Simple simple = this.properties.getSimple();\n      \/\/ spring.task.execution.simple.concurrency-limit\n      builder = builder.concurrencyLimit(simple.getConcurrencyLimit());\n      TaskExecutionProperties.Shutdown shutdown = this.properties.getShutdown();\n      \/\/ spring.task.execution.shutdown.await-termination\n      if (shutdown.isAwaitTermination()) {\n          \/\/ spring.task.execution.shutdown.await-termination-period\n          builder = builder.taskTerminationTimeout(shutdown.getAwaitTerminationPeriod());\n      }\n\n      return builder;\n  }\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki dracula\" style=\"background-color: #282A36\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F8F8F2\">  @<\/span><span style=\"color: #8BE9FD; font-style: italic\">Bean<\/span><span style=\"color: #F8F8F2\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #BD93F9\">name<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #FF79C6\">=<\/span><span style=\"color: #F8F8F2\"> {<\/span><span style=\"color: #E9F284\">&quot;<\/span><span style=\"color: #F1FA8C\">simpleAsyncTaskExecutorBuilder<\/span><span style=\"color: #E9F284\">&quot;<\/span><span style=\"color: #F8F8F2\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  @<\/span><span style=\"color: #8BE9FD; font-style: italic\">ConditionalOnMissingBean<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  @<\/span><span style=\"color: #8BE9FD; font-style: italic\">ConditionalOnThreading<\/span><span style=\"color: #F8F8F2\">(Threading.VIRTUAL)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  <\/span><span style=\"color: #8BE9FD; font-style: italic\">SimpleAsyncTaskExecutorBuilder<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #50FA7B\">simpleAsyncTaskExecutorBuilderVirtualThreads<\/span><span style=\"color: #F8F8F2\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #8BE9FD; font-style: italic\">SimpleAsyncTaskExecutorBuilder<\/span><span style=\"color: #F8F8F2\"> builder <\/span><span style=\"color: #FF79C6\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #BD93F9; font-style: italic\">this<\/span><span style=\"color: #F8F8F2\">.<\/span><span style=\"color: #50FA7B\">builder<\/span><span style=\"color: #F8F8F2\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      builder <\/span><span style=\"color: #FF79C6\">=<\/span><span style=\"color: #F8F8F2\"> builder.<\/span><span style=\"color: #50FA7B\">virtualThreads<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #BD93F9\">true<\/span><span style=\"color: #F8F8F2\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #FF79C6\">return<\/span><span style=\"color: #F8F8F2\"> builder;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  <\/span><span style=\"color: #FF79C6\">private<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #8BE9FD; font-style: italic\">SimpleAsyncTaskExecutorBuilder<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #50FA7B\">builder<\/span><span style=\"color: #F8F8F2\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #8BE9FD; font-style: italic\">SimpleAsyncTaskExecutorBuilder<\/span><span style=\"color: #F8F8F2\"> builder <\/span><span style=\"color: #FF79C6\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #FF79C6; font-weight: bold\">new<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #50FA7B\">SimpleAsyncTaskExecutorBuilder<\/span><span style=\"color: #F8F8F2\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #6272A4\">\/\/ spring.task.execution.thread-name-prefix<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      builder <\/span><span style=\"color: #FF79C6\">=<\/span><span style=\"color: #F8F8F2\"> builder.<\/span><span style=\"color: #50FA7B\">threadNamePrefix<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #BD93F9; font-style: italic\">this<\/span><span style=\"color: #F8F8F2\">.properties.<\/span><span style=\"color: #50FA7B\">getThreadNamePrefix<\/span><span style=\"color: #F8F8F2\">());<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #8BE9FD; font-style: italic\">Stream<\/span><span style=\"color: #F8F8F2\"> var10001 <\/span><span style=\"color: #FF79C6\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #BD93F9; font-style: italic\">this<\/span><span style=\"color: #F8F8F2\">.taskExecutorCustomizers.<\/span><span style=\"color: #50FA7B\">orderedStream<\/span><span style=\"color: #F8F8F2\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      Objects.<\/span><span style=\"color: #50FA7B\">requireNonNull<\/span><span style=\"color: #F8F8F2\">(var10001);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      builder <\/span><span style=\"color: #FF79C6\">=<\/span><span style=\"color: #F8F8F2\"> builder.<\/span><span style=\"color: #50FA7B\">customizers<\/span><span style=\"color: #F8F8F2\">(var10001<\/span><span style=\"color: #FF79C6\">::<\/span><span style=\"color: #F8F8F2\">iterator);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      builder <\/span><span style=\"color: #FF79C6\">=<\/span><span style=\"color: #F8F8F2\"> builder.<\/span><span style=\"color: #50FA7B\">taskDecorator<\/span><span style=\"color: #F8F8F2\">((TaskDecorator)<\/span><span style=\"color: #BD93F9; font-style: italic\">this<\/span><span style=\"color: #F8F8F2\">.taskDecorator.<\/span><span style=\"color: #50FA7B\">getIfUnique<\/span><span style=\"color: #F8F8F2\">());<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #8BE9FD; font-style: italic\">TaskExecutionProperties<\/span><span style=\"color: #F8F8F2\">.<\/span><span style=\"color: #8BE9FD; font-style: italic\">Simple<\/span><span style=\"color: #F8F8F2\"> simple <\/span><span style=\"color: #FF79C6\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #BD93F9; font-style: italic\">this<\/span><span style=\"color: #F8F8F2\">.properties.<\/span><span style=\"color: #50FA7B\">getSimple<\/span><span style=\"color: #F8F8F2\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #6272A4\">\/\/ spring.task.execution.simple.concurrency-limit<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      builder <\/span><span style=\"color: #FF79C6\">=<\/span><span style=\"color: #F8F8F2\"> builder.<\/span><span style=\"color: #50FA7B\">concurrencyLimit<\/span><span style=\"color: #F8F8F2\">(simple.<\/span><span style=\"color: #50FA7B\">getConcurrencyLimit<\/span><span style=\"color: #F8F8F2\">());<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #8BE9FD; font-style: italic\">TaskExecutionProperties<\/span><span style=\"color: #F8F8F2\">.<\/span><span style=\"color: #8BE9FD; font-style: italic\">Shutdown<\/span><span style=\"color: #F8F8F2\"> shutdown <\/span><span style=\"color: #FF79C6\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #BD93F9; font-style: italic\">this<\/span><span style=\"color: #F8F8F2\">.properties.<\/span><span style=\"color: #50FA7B\">getShutdown<\/span><span style=\"color: #F8F8F2\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #6272A4\">\/\/ spring.task.execution.shutdown.await-termination<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #FF79C6\">if<\/span><span style=\"color: #F8F8F2\"> (shutdown.<\/span><span style=\"color: #50FA7B\">isAwaitTermination<\/span><span style=\"color: #F8F8F2\">()) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">          <\/span><span style=\"color: #6272A4\">\/\/ spring.task.execution.shutdown.await-termination-period<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">          builder <\/span><span style=\"color: #FF79C6\">=<\/span><span style=\"color: #F8F8F2\"> builder.<\/span><span style=\"color: #50FA7B\">taskTerminationTimeout<\/span><span style=\"color: #F8F8F2\">(shutdown.<\/span><span style=\"color: #50FA7B\">getAwaitTerminationPeriod<\/span><span style=\"color: #F8F8F2\">());<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">      <\/span><span style=\"color: #FF79C6\">return<\/span><span style=\"color: #F8F8F2\"> builder;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  }<\/span><\/span><\/code><\/pre><span style=\"display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#282A36;color:#efefe1;font-size:12px;line-height:1;position:relative\">Java<\/span><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2>\uc870\uc2ec\ud560 \uc810<\/h2>\n\n\n\n<ul>\n<li><a href=\"https:\/\/redutan.synology.me\/wordpress\/2024\/04\/22\/virtual-thread-pinning-issue%ec%9e%91%ec%84%b1-%ec%a4%91\/\">\bISSUE: Pinning inside synchronized<\/a>: <code>ReentrantLock<\/code>\ub97c \uc0ac\uc6a9\ud558\uc790. \ub77c\uc774\ube0c\ub7ec\ub9ac \uc9c0\uc6d0\uc744 \uae30\ub2e4\ub9ac\uc790.<\/li>\n\n\n\n<li>\uacfc\ub3c4\ud55c ThreadLocal: ThreadLocal \ub0b4 \ubb34\uac70\uc6b4 \uac1d\uccb4\ub97c \uc0dd\uc131\ud558\uba74 Platform Thread\ubcf4\ub2e4 \ub290\ub824\uc9c8 \uc218 \uc788\ub2e4.<\/li>\n\n\n\n<li>native \uba54\uc11c\ub4dc \ud638\ucd9c: \uc774\uac74 \ub2f5\uc774 \uc5c6&#8230;<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2>Case Study: \bCircuit Breaker\uc5d0\ub9cc Virtual Thread \uc801\uc6a9<\/h2>\n\n\n\n<p>\ub808\uac70\uc2dc jdbc-driver\uacfc \uac19\uc774 Pinning \uc774\uc288\uac00 \uc788\ub294 \uacbd\uc6b0\uc5d0\ub294 \uae30\ubcf8\uc801\uc73c\ub85c\ub294 Platform Thread\ub97c \uc801\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\uc2b5\ub2c8\ub2e4.<br>\ud558\uc9c0\ub9cc \uadf8\ub7f4\uc9c0\ub77c\ub3c4 \ubd80\ubd84\uc801\uc73c\ub85c Virtual Thread\ub97c \uc801\uc6a9\ud560 \uc218 \uc788\uc8e0. \uc544\uc2dc\ub2e4\uc2dc\ud53c I\/O \uc9c0\uc5f0\uc774 \uc788\ub294 api-client\ub97c \uad6c\ud604\ud558\ub294 \uacbd\uc6b0\uc5d0\ub294 \ubd80\ubd84\uc5d0 Virtual Thread\ub97c \uc801\uc6a9\ud558\uba74 \uc544\uc8fc \uc88b\uc744 \uac83 \uac19\ub124\uc694.<br><br>\ud604\uc7ac \uc81c\uac00 \uc6b4\uc601\ud558\ub294 \uc11c\ube44\uc2a4\ub294 api \ud638\ucd9c \uc2dc open-fein\uc744 \uc0ac\uc6a9\ud558\uace0 \uc788\uc2b5\ub2c8\ub2e4. \uac70\uae30\uc5d0 resilience4j\uc758 circuit-breaker\uae4c\uc9c0 \uc801\uc6a9\ud55c \uc0c1\ud0dc\uc774\uc8e0. \ub300\ubd80\ubd84\uc758 Java \uc6d4\ub4dc\uc5d0\uc11c circuit-breaker \uc124\uc815 \uc2dc \uc138\ub9c8\ud3ec\uc5b4 \ubcf4\ub2e4\ub294 Thread\ub97c \uae30\ubc18\uc73c\ub85c \uaca9\ub9ac\ud558\ub294 \uac83\uc744 \ucd94\ucc9c\ud569\ub2c8\ub2e4. \ubb3c\ub860 \uc77c\ubd80 \uc0c1\ud669 <sup><sub>ex: \ub85c\uceec \uba54\ubaa8\ub9ac \uce90\uc2dc \uc870\ud68c\uc640 \uac19\uc774 I\/O \ub300\uae30\uac00 \uc801\uc740 \uacbd\uc6b0<\/sub><\/sup> \uc5d0\uc11c Thread \uc0dd\uc131 \ube44\uc6a9 \ub54c\ubb38\uc5d0 \uc138\ub9c8\ud3ec\uc5b4\uac00 \uc720\ub9ac\ud55c \uacbd\uc6b0\ub3c4 \uc788\uc9c0\uc2b5\ub2c8\ub2e4. \uc774\ub7f0 \uacbd\uc6b0\ub77c\uba74 \uad73\uc774 Virtual Thread \uc77c\uc9c0\ub77c\ub3c4 \uc0ac\uc6a9 \uc548\ud558\ub294 \uac83\uc774 \ub0ab\uc2b5\ub2c8\ub2e4. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"782\" src=\"https:\/\/redutan.synology.me\/wordpress\/wp-content\/uploads\/2024\/04\/image-17-1024x782.png\" alt=\"\" class=\"wp-image-304\" srcset=\"https:\/\/redutan.synology.me\/wordpress\/wp-content\/uploads\/2024\/04\/image-17-1024x782.png 1024w, https:\/\/redutan.synology.me\/wordpress\/wp-content\/uploads\/2024\/04\/image-17-300x229.png 300w, https:\/\/redutan.synology.me\/wordpress\/wp-content\/uploads\/2024\/04\/image-17-768x587.png 768w, https:\/\/redutan.synology.me\/wordpress\/wp-content\/uploads\/2024\/04\/image-17.png 1223w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">\ucd9c\ucc98: https:\/\/netflixtechblog.com\/fault-tolerance-in-a-high-volume-distributed-system-91ab4faae74a<\/figcaption><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h3>Resilence4jConfig<\/h3>\n\n\n\n<p><code>Customize&lt;Resilience4JCircuitBreakerFactory&gt;<\/code> \ud0c0\uc785\uc73c\ub85c \uc2a4\ud504\ub9c1 Bean\uc744 \uc0dd\uc131\ud569\ub2c8\ub2e4. <br>\uaca9\ub9ac \uc2dc Virtual Thread \ub97c \uc774\uc6a9\ud558\uac8c \ucee4\uc2a4\ud130\ub9c8\uc774\uc9d5 \ud558\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282A36\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"    @Bean\n    public Customizer&lt;Resilience4JCircuitBreakerFactory&gt; circuitBreakerCustomizer() {\n        return factory -&gt; {\n            VirtualThreadExecutor executor = new VirtualThreadExecutor(&quot;circuit-breaker-&quot;);\n            factory.configureExecutorService(executor);\n        };\n    }\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki dracula\" style=\"background-color: #282A36\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F8F8F2\">    @<\/span><span style=\"color: #8BE9FD; font-style: italic\">Bean<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #FF79C6\">public<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #8BE9FD; font-style: italic\">Customizer<\/span><span style=\"color: #FF79C6\">&lt;<\/span><span style=\"color: #F8F8F2\">Resilience4JCircuitBreakerFactory<\/span><span style=\"color: #FF79C6\">&gt;<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #50FA7B\">circuitBreakerCustomizer<\/span><span style=\"color: #F8F8F2\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        <\/span><span style=\"color: #FF79C6\">return<\/span><span style=\"color: #F8F8F2\"> factory <\/span><span style=\"color: #8BE9FD; font-style: italic\">-&gt;<\/span><span style=\"color: #F8F8F2\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            <\/span><span style=\"color: #8BE9FD; font-style: italic\">VirtualThreadExecutor<\/span><span style=\"color: #F8F8F2\"> executor <\/span><span style=\"color: #FF79C6\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #FF79C6; font-weight: bold\">new<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #50FA7B\">VirtualThreadExecutor<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #E9F284\">&quot;<\/span><span style=\"color: #F1FA8C\">circuit-breaker-<\/span><span style=\"color: #E9F284\">&quot;<\/span><span style=\"color: #F8F8F2\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">            factory.<\/span><span style=\"color: #50FA7B\">configureExecutorService<\/span><span style=\"color: #F8F8F2\">(executor);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        };<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    }<\/span><\/span><\/code><\/pre><span style=\"display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#282A36;color:#efefe1;font-size:12px;line-height:1;position:relative\">Java<\/span><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h3>\ud558\uc9c0\ub9cc&#8230;<\/h3>\n\n\n\n<p><a href=\"https:\/\/github.com\/resilience4j\/resilience4j\/issues\/2122\" target=\"_blank\" rel=\"noopener\" title=\"\">[question] Is circuitbreaker virtual thread \/ loom friendly?<\/a><\/p>\n\n\n\n<p>Resilence4j github \uc800\uc7a5\uc18c\uc5d0 \uc704\uc640 \uac19\uc740 \uc774\uc288\uac00 \ub4f1\ub85d\ub418\uc5b4 \uc788\ub294\ub370, \ub2f5\ubcc0\uc744 \ubcf4\ub2c8 \ud604\uc7ac Virtual Thread \uc9c0\uc6d0\uc774 \ud798\ub4e4\ub2e4\uace0 \ud558\ub124\uc694. \uc2dc\uac04\uc774 \uc5c6\uc5b4\uc11c \uc624\ud508\uc18c\uc2a4 \ucee4\ubba4\ub2c8\ud2f0\uc758 \ub3c4\uc6c0\uc744 \uc694\uccad\ud558\uace0 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Hi, there is no release planned. I currently don't have time to develop anymore.\nWe need contributions from the community to make it Loom friendly<\/code><\/pre>\n\n\n\n<p>\uc801\uc6a9\ud558\ub294 \ubaa8\uc2b5\uc744 \ubcf4\uc5ec\ub4dc\ub9ac\uace0 \uc2f6\uc5c8\ub294\ub370 \ub108\ubb34 \uc544\uc27d\ub124\uc694. \u3160\u3160 \uc81c\uac00 \uc2dc\uac04\uc774 \uc788\ub2e4\uba74 Pull Request\ub77c\ub3c4 \uc62c\ub824\uc11c \uae30\uc5ec\ud558\uace0 \uc2f6\ub124\uc694.<br><br>\uc544\uc27d\uc9c0\ub9cc <code>-Djdk.tracePinnedThreads=short<\/code> JVM \uc635\uc158\uc73c\ub85c \uae30\ub3d9\ud574\uc11c <code>synchronized<\/code> \uc774\uc288\uac00 \ubc1c\uc0dd\ud558\ub294 \ubd80\ubd84\uc744 \ud655\uc778\ud558\uba74\uc11c \ub9c8\ubb34\ub9ac \ud558\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282A36\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"Thread[#87,ForkJoinPool-1-worker-1,5,CarrierThreads]\n  com.example.controller.internal.InfraInternalController.infra(InfraInternalController.java:95) &lt;== monitors:1\n    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:268) &lt;== monitors:1\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki dracula\" style=\"background-color: #282A36\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #8BE9FD; font-style: italic\">Thread<\/span><span style=\"color: #F8F8F2\">[#<\/span><span style=\"color: #BD93F9\">87<\/span><span style=\"color: #F8F8F2\">,ForkJoinPool<\/span><span style=\"color: #FF79C6\">-<\/span><span style=\"color: #BD93F9\">1<\/span><span style=\"color: #FF79C6\">-<\/span><span style=\"color: #F8F8F2\">worker<\/span><span style=\"color: #FF79C6\">-<\/span><span style=\"color: #BD93F9\">1<\/span><span style=\"color: #F8F8F2\">,<\/span><span style=\"color: #BD93F9\">5<\/span><span style=\"color: #F8F8F2\">,CarrierThreads]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">  com.example.controller.internal.InfraInternalController.<\/span><span style=\"color: #50FA7B\">infra<\/span><span style=\"color: #F8F8F2\">(InfraInternalController.java<\/span><span style=\"color: #FF79C6\">:<\/span><span style=\"color: #BD93F9\">95<\/span><span style=\"color: #F8F8F2\">) <\/span><span style=\"color: #FF79C6\">&lt;==<\/span><span style=\"color: #F8F8F2\"> monitors<\/span><span style=\"color: #FF79C6\">:<\/span><span style=\"color: #BD93F9\">1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    org.springframework.web.filter.DelegatingFilterProxy.<\/span><span style=\"color: #50FA7B\">doFilter<\/span><span style=\"color: #F8F8F2\">(DelegatingFilterProxy.java<\/span><span style=\"color: #FF79C6\">:<\/span><span style=\"color: #BD93F9\">268<\/span><span style=\"color: #F8F8F2\">) <\/span><span style=\"color: #FF79C6\">&lt;==<\/span><span style=\"color: #F8F8F2\"> monitors<\/span><span style=\"color: #FF79C6\">:<\/span><span style=\"color: #BD93F9\">1<\/span><\/span><\/code><\/pre><span style=\"display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#282A36;color:#efefe1;font-size:12px;line-height:1;position:relative\">Java<\/span><\/div>\n\n\n\n<p><code>InfraInternalController.java<\/code><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282A36\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"    @Operation(summary = &quot;Infra, Service \uc811\uc18d \uc5ec\ubd80 \ud655\uc778 API&quot;)\n    @GetMapping\n\t\t\/\/ synchronized\n    public synchronized InfraResponse infra() {\n        \/\/ InfraInternalController.java:95\n        return new InfraResponse(isConnect1(), isConnect2(), isConnect3(), isConnect4(),\n                                 isConnect5(), isConnectS3(), isConnectSes(), isConnectPrimaryDb(), isConnectOtherDb());\n    }\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki dracula\" style=\"background-color: #282A36\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F8F8F2\">    @<\/span><span style=\"color: #8BE9FD; font-style: italic\">Operation<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #BD93F9\">summary<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #FF79C6\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #E9F284\">&quot;<\/span><span style=\"color: #F1FA8C\">Infra, Service \uc811\uc18d \uc5ec\ubd80 \ud655\uc778 API<\/span><span style=\"color: #E9F284\">&quot;<\/span><span style=\"color: #F8F8F2\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    @<\/span><span style=\"color: #8BE9FD; font-style: italic\">GetMapping<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t<\/span><span style=\"color: #6272A4\">\/\/ synchronized<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    <\/span><span style=\"color: #FF79C6\">public<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #FF79C6\">synchronized<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #8BE9FD; font-style: italic\">InfraResponse<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #50FA7B\">infra<\/span><span style=\"color: #F8F8F2\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        <\/span><span style=\"color: #6272A4\">\/\/ InfraInternalController.java:95<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">        <\/span><span style=\"color: #FF79C6\">return<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #FF79C6; font-weight: bold\">new<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #50FA7B\">InfraResponse<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #50FA7B\">isConnect1<\/span><span style=\"color: #F8F8F2\">(), <\/span><span style=\"color: #50FA7B\">isConnect2<\/span><span style=\"color: #F8F8F2\">(), <\/span><span style=\"color: #50FA7B\">isConnect3<\/span><span style=\"color: #F8F8F2\">(), <\/span><span style=\"color: #50FA7B\">isConnect4<\/span><span style=\"color: #F8F8F2\">(),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">                                 <\/span><span style=\"color: #50FA7B\">isConnect5<\/span><span style=\"color: #F8F8F2\">(), <\/span><span style=\"color: #50FA7B\">isConnectS3<\/span><span style=\"color: #F8F8F2\">(), <\/span><span style=\"color: #50FA7B\">isConnectSes<\/span><span style=\"color: #F8F8F2\">(), <\/span><span style=\"color: #50FA7B\">isConnectPrimaryDb<\/span><span style=\"color: #F8F8F2\">(), <\/span><span style=\"color: #50FA7B\">isConnectOtherDb<\/span><span style=\"color: #F8F8F2\">());<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">    }<\/span><\/span><\/code><\/pre><span style=\"display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#282A36;color:#efefe1;font-size:12px;line-height:1;position:relative\">Java<\/span><\/div>\n\n\n\n<p><code>DelegatingFilterProxy.java<\/code><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#282A36\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\t@Override\n\tpublic void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)\n\t\t\tthrows ServletException, IOException {\n\n\t\tFilter delegateToUse = this.delegate;\n\t\tif (delegateToUse == null) {\n\t\t  \/\/ synchronized\n\t\t\tsynchronized (this.delegateMonitor) {\n\t\t\t\tdelegateToUse = this.delegate;\n\t\t\t\tif (delegateToUse == null) {\n\t\t\t\t\tWebApplicationContext wac = findWebApplicationContext();\n\t\t\t\t\tif (wac == null) {\n\t\t\t\t\t\tthrow new IllegalStateException(&quot;No WebApplicationContext found: &quot; +\n\t\t\t\t\t\t\t\t&quot;no ContextLoaderListener or DispatcherServlet registered?&quot;);\n\t\t\t\t\t}\n\t\t\t\t\tdelegateToUse = initDelegate(wac);\n\t\t\t\t}\n\t\t\t\tthis.delegate = delegateToUse;\n\t\t\t}\n\t\t}\n\n\t\t\/\/ DelegatingFilterProxy.java:268\n\t\tinvokeDelegate(delegateToUse, request, response, filterChain);\n\t}\" style=\"color:#F8F8F2;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki dracula\" style=\"background-color: #282A36\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F8F8F2\">\t@<\/span><span style=\"color: #8BE9FD; font-style: italic\">Override<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t<\/span><span style=\"color: #FF79C6\">public<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #8BE9FD; font-style: italic\">void<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #50FA7B\">doFilter<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #8BE9FD; font-style: italic\">ServletRequest<\/span><span style=\"color: #F8F8F2\"> request, <\/span><span style=\"color: #8BE9FD; font-style: italic\">ServletResponse<\/span><span style=\"color: #F8F8F2\"> response, <\/span><span style=\"color: #8BE9FD; font-style: italic\">FilterChain<\/span><span style=\"color: #F8F8F2\"> filterChain)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\tthrows ServletException, IOException {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t<\/span><span style=\"color: #8BE9FD; font-style: italic\">Filter<\/span><span style=\"color: #F8F8F2\"> delegateToUse <\/span><span style=\"color: #FF79C6\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #BD93F9; font-style: italic\">this<\/span><span style=\"color: #F8F8F2\">.delegate;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t<\/span><span style=\"color: #FF79C6\">if<\/span><span style=\"color: #F8F8F2\"> (delegateToUse <\/span><span style=\"color: #FF79C6\">==<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #BD93F9\">null<\/span><span style=\"color: #F8F8F2\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t  <\/span><span style=\"color: #6272A4\">\/\/ synchronized<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t<\/span><span style=\"color: #FF79C6\">synchronized<\/span><span style=\"color: #F8F8F2\"> (<\/span><span style=\"color: #BD93F9; font-style: italic\">this<\/span><span style=\"color: #F8F8F2\">.delegateMonitor) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t\tdelegateToUse <\/span><span style=\"color: #FF79C6\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #BD93F9; font-style: italic\">this<\/span><span style=\"color: #F8F8F2\">.delegate;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t\t<\/span><span style=\"color: #FF79C6\">if<\/span><span style=\"color: #F8F8F2\"> (delegateToUse <\/span><span style=\"color: #FF79C6\">==<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #BD93F9\">null<\/span><span style=\"color: #F8F8F2\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t\t\t<\/span><span style=\"color: #8BE9FD; font-style: italic\">WebApplicationContext<\/span><span style=\"color: #F8F8F2\"> wac <\/span><span style=\"color: #FF79C6\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #50FA7B\">findWebApplicationContext<\/span><span style=\"color: #F8F8F2\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t\t\t<\/span><span style=\"color: #FF79C6\">if<\/span><span style=\"color: #F8F8F2\"> (wac <\/span><span style=\"color: #FF79C6\">==<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #BD93F9\">null<\/span><span style=\"color: #F8F8F2\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t\t\t\t<\/span><span style=\"color: #FF79C6\">throw<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #FF79C6; font-weight: bold\">new<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #50FA7B\">IllegalStateException<\/span><span style=\"color: #F8F8F2\">(<\/span><span style=\"color: #E9F284\">&quot;<\/span><span style=\"color: #F1FA8C\">No WebApplicationContext found: <\/span><span style=\"color: #E9F284\">&quot;<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #FF79C6\">+<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t\t\t\t\t\t<\/span><span style=\"color: #E9F284\">&quot;<\/span><span style=\"color: #F1FA8C\">no ContextLoaderListener or DispatcherServlet registered?<\/span><span style=\"color: #E9F284\">&quot;<\/span><span style=\"color: #F8F8F2\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t\t\t}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t\t\tdelegateToUse <\/span><span style=\"color: #FF79C6\">=<\/span><span style=\"color: #F8F8F2\"> <\/span><span style=\"color: #50FA7B\">initDelegate<\/span><span style=\"color: #F8F8F2\">(wac);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t\t}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t\t<\/span><span style=\"color: #BD93F9; font-style: italic\">this<\/span><span style=\"color: #F8F8F2\">.delegate <\/span><span style=\"color: #FF79C6\">=<\/span><span style=\"color: #F8F8F2\"> delegateToUse;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t\t}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t<\/span><span style=\"color: #6272A4\">\/\/ DelegatingFilterProxy.java:268<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t\t<\/span><span style=\"color: #50FA7B\">invokeDelegate<\/span><span style=\"color: #F8F8F2\">(delegateToUse, request, response, filterChain);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F8F8F2\">\t}<\/span><\/span><\/code><\/pre><span style=\"display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#282A36;color:#efefe1;font-size:12px;line-height:1;position:relative\">Java<\/span><\/div>\n","protected":false},"excerpt":{"rendered":"<p>\uc774 \uae00\uc744 \uc77d\uae30 \uc804\uc5d0 \uc544\ub798 \uae00\uc744 \uba3c\uc800 \uc77d\uae30\ub97c \ucd94\ucc9c\ub4dc\ub9bd\ub2c8\ub2e4. \uba3c\uc800 Virtual Thread\ub97c \uc801\uc6a9\ud558\uae30 \uc804\uc5d0 \uc81c\uc57d\uc5d0 \ub300\ud55c \uc774\ud574\uac00 \ud544\uc694\ud569\ub2c8\ub2e4. \bISSUE: Pinning inside synchronized spring-boot 3.2.x \uc5d0\uc11c \ub4dc\ub514\uc5b4 JEP-444 Virtual Thread \uae30\ub2a5\uc744 \ud65c\uc131\ud654 \uc2dc\ud0ac \uc218 \uc788\uc2b5\ub2c8\ub2e4.Virtual Thread \uc640 \uad00\ub828\ub41c \uc790\uc138\ud55c \ub0b4\uc6a9\uc744 \uc54c\uace0 \uc2f6\uc73c\uc2dc\uba74, Oracle \uacf5\uc2dd \ubb38\uc11c\ub97c \ud655\uc778\ud558\ub294 \uac83\uc744 \ucd94\ucc9c\ud569\ub2c8\ub2e4.(\uae30\uc874 Thread\ub294 Platform Thread\ub77c\uace0 \ubd80\ub974\ub124\uc694.) \uacb0\ub860 \ubd80\ud130 \ub9d0\uc500\ub4dc\ub9ac\uba74 \uc11c\ube44\uc2a4\uac00 &#8230; <a title=\"Java 21 Virtual Thread Configuration on spring-boot 3.2.x\" class=\"read-more\" href=\"https:\/\/redutan.synology.me\/wordpress\/2024\/04\/22\/java-21-virtual-thread-configuration-on-spring-boot-3-2-x\/\" aria-label=\"Read more about Java 21 Virtual Thread Configuration on spring-boot 3.2.x\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":304,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[28],"tags":[46,9,26,39],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/redutan.synology.me\/wordpress\/wp-json\/wp\/v2\/posts\/243"}],"collection":[{"href":"https:\/\/redutan.synology.me\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/redutan.synology.me\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/redutan.synology.me\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/redutan.synology.me\/wordpress\/wp-json\/wp\/v2\/comments?post=243"}],"version-history":[{"count":23,"href":"https:\/\/redutan.synology.me\/wordpress\/wp-json\/wp\/v2\/posts\/243\/revisions"}],"predecessor-version":[{"id":307,"href":"https:\/\/redutan.synology.me\/wordpress\/wp-json\/wp\/v2\/posts\/243\/revisions\/307"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/redutan.synology.me\/wordpress\/wp-json\/wp\/v2\/media\/304"}],"wp:attachment":[{"href":"https:\/\/redutan.synology.me\/wordpress\/wp-json\/wp\/v2\/media?parent=243"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/redutan.synology.me\/wordpress\/wp-json\/wp\/v2\/categories?post=243"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/redutan.synology.me\/wordpress\/wp-json\/wp\/v2\/tags?post=243"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}