- ID da verificação
- 57818096-c0f7-42ef-a711-647699e92b19Concluído
- URL enviado:
- https://jb.gg/ij-platform-threadingRedirecionado
- Relatório concluído:
Ligações · 32 encontradas
As ligações de saída identificadas na página
Hiperligação | Texto |
---|---|
https://jb.gg/ipe | IntelliJ Platform Explorer |
https://github.com/JetBrains/intellij-sdk-docs/edit/main/topics/basics/architectural_overview/threading_model.md | Edit page |
https://docs.oracle.com/javase/tutorial/essential/concurrency/index.html | Java Concurrency |
https://docs.oracle.com/javase%2Ftutorial%2Fuiswing%2F%2F/index.html | Swing |
https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html | Event Dispatch Thread |
https://w.wiki/7dBy | read-write (RW) lock |
https://youtrack.jetbrains.com/issue/IJPL-53 | allow writing data from any thread |
https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/core-api/src/com/intellij/openapi/application/Application.java | Application.runWriteAction() |
https://docs.oracle.com/javase/8/docs/api/javax/swing/SwingUtilities.html#invokeLater-java.lang.Runnable- | SwingUtilities.invokeLater() |
https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/util/ui/src/com/intellij/util/ui/UIUtil.java | UIUtil.invokeLaterIfNeeded() |
Variáveis JavaScript · 31 encontradas
Variáveis JavaScript globais carregadas no objeto janela de uma página são variáveis declaradas fora das funções e acessíveis de qualquer parte do código dentro do âmbito atual
Nome | Tipo |
---|---|
0 | object |
onbeforetoggle | object |
documentPictureInPicture | object |
onscrollend | object |
dataLayer | object |
google_tag_manager | object |
postscribe | function |
google_tag_manager_external | object |
google_tag_data | object |
webpackChunkwebhelp_template | object |
Mensagens de registo da consola · 0 encontradas
Mensagens registadas na consola web
HTML
O corpo HTML em bruto da página
<!DOCTYPE html SYSTEM "about:legacy-compat"><html lang="en-US" data-preset="contrast" data-primary-color="#307FFF" data-resizable-sidebar="true" class="theme-light"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta charset="UTF-8"><meta name="built-on" content="2024-12-10T09:47:37.114987445"><meta name="build-number" content="813"><!-- Google Tag Manager -->
<script type="text/javascript" async="" src="https://www.googletagmanager.com/gtag/destination?id=AW-1071903267&l=dataLayer&cx=c&gtm=45He4cb0v558776za200"></script><script type="text/javascript" async="" src="https://www.googletagmanager.com/gtag/js?id=G-M8TDRLXFQH&l=dataLayer&cx=c&gtm=45He4cb0v558776za200"></script><script type="text/javascript" async="" src="https://www.googletagmanager.com/gtag/js?id=G-9J976DJZ68&l=dataLayer&cx=c&gtm=45He4cb0v558776za200"></script><script async="" src="https://www.googletagmanager.com/gtm.js?id=GTM-5P98"></script><script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-5P98');</script>
<!-- End Google Tag Manager -->
<title>Threading Model | IntelliJ Platform Plugin SDK</title><script type="application/json" id="virtual-toc-data">[{"id":"read-write-lock","level":0,"title":"Read-Write Lock","anchor":"#read-write-lock"},{"id":"locks-and-edt","level":1,"title":"Locks and EDT","anchor":"#locks-and-edt"},{"id":"accessing-data","level":0,"title":"Accessing Data","anchor":"#accessing-data"},{"id":"read-actions","level":1,"title":"Read Actions","anchor":"#read-actions"},{"id":"write-actions","level":1,"title":"Write Actions","anchor":"#write-actions"},{"id":"invoking-operations-on-edt-and-modality","level":0,"title":"Invoking Operations on EDT and Modality","anchor":"#invoking-operations-on-edt-and-modality"},{"id":"read-action-cancellability","level":0,"title":"Read Action Cancellability","anchor":"#read-action-cancellability"},{"id":"cancellable-read-actions-api","level":1,"title":"Cancellable Read Actions API","anchor":"#cancellable-read-actions-api"},{"id":"avoiding-ui-freezes","level":0,"title":"Avoiding UI Freezes","anchor":"#avoiding-ui-freezes"},{"id":"don-t-perform-long-operations-on-edt","level":1,"title":"Don\u0027t Perform Long Operations on EDT","anchor":"#don-t-perform-long-operations-on-edt"},{"id":"event-listeners","level":1,"title":"Event Listeners","anchor":"#event-listeners"},{"id":"vfs-events","level":1,"title":"VFS Events","anchor":"#vfs-events"},{"id":"faq","level":0,"title":"FAQ","anchor":"#faq"},{"id":"how-to-check-whether-the-current-thread-is-the-edtui-thread","level":1,"title":"How to check whether the current thread is the EDT/UI thread?","anchor":"#how-to-check-whether-the-current-thread-is-the-edtui-thread"},{"id":"why-write-actions-are-currently-allowed-only-on-edt","level":1,"title":"Why write actions are currently allowed only on EDT?","anchor":"#why-write-actions-are-currently-allowed-only-on-edt"},{"id":"why-can-write-intent-lock-be-acquired-from-any-thread-but-write-lock-only-from-edt","level":1,"title":"Why can write intent lock be acquired from any thread but write lock only from EDT?","anchor":"#why-can-write-intent-lock-be-acquired-from-any-thread-but-write-lock-only-from-edt"}]</script><script type="application/json" id="topic-shortcuts"></script><link href="https://resources.jetbrains.com/writerside/apidoc/6.10.0-b518/app.css" rel="stylesheet"><link rel="manifest" href="https://www.jetbrains.com/site.webmanifest"><meta name="msapplication-TileColor" content="#000000"><link rel="apple-touch-icon" sizes="180x180" href="https://jetbrains.com/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="https://jetbrains.com/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="https://jetbrains.com/favicon-16x16.png"><meta name="msapplication-TileImage" content="https://resources.jetbrains.com/storage/ui/favicons/mstile-144x144.png"><meta name="msapplication-square70x70logo" content="https://resources.jetbrains.com/storage/ui/favicons/mstile-70x70.png"><meta name="msapplication-square150x150logo" content="https://resources.jetbrains.com/storage/ui/favicons/mstile-150x150.png"><meta name="msapplication-wide310x150logo" content="https://resources.jetbrains.com/storage/ui/favicons/mstile-310x150.png"><meta name="msapplication-square310x310logo" content="https://resources.jetbrains.com/storage/ui/favicons/mstile-310x310.png"><meta name="image" content="https://resources.jetbrains.com/storage/products/jetbrains/img/meta/preview.png"><!-- Open Graph --><meta property="og:title" content="Threading Model | IntelliJ Platform Plugin SDK"><meta property="og:description" content=""><meta property="og:image" content="https://resources.jetbrains.com/storage/products/jetbrains/img/meta/preview.png"><meta property="og:site_name" content="IntelliJ Platform Plugin SDK Help"><meta property="og:type" content="website"><meta property="og:locale" content="en_US"><meta property="og:url" content="https://plugins.jetbrains.com/docs/intellij/threading-model.html"><!-- End Open Graph --><!-- Twitter Card --><meta name="twitter:card" content="summary_large_image"><meta name="twitter:site" content="@JBPlatform"><meta name="twitter:title" content="Threading Model | IntelliJ Platform Plugin SDK"><meta name="twitter:description" content=""><meta name="twitter:creator" content="@JBPlatform"><meta name="twitter:image:src" content="https://resources.jetbrains.com/storage/products/jetbrains/img/meta/preview.png"><!-- End Twitter Card --><!-- Schema.org WebPage --><script type="application/ld+json">{
"@context": "http://schema.org",
"@type": "WebPage",
"@id": "https://plugins.jetbrains.com/docs/intellij/threading-model.html#webpage",
"url": "https://plugins.jetbrains.com/docs/intellij/threading-model.html",
"name": "Threading Model | IntelliJ Platform Plugin SDK",
"description": "",
"image": "https://resources.jetbrains.com/storage/products/jetbrains/img/meta/preview.png",
"inLanguage":"en-US"
}</script><!-- End Schema.org --><!-- Schema.org WebSite --><script type="application/ld+json">{
"@type": "WebSite",
"@id": "https://plugins.jetbrains.com/docs/intellij/#website",
"url": "https://plugins.jetbrains.com/docs/intellij/",
"name": "IntelliJ Platform Plugin SDK Help"
}</script><!-- End Schema.org --><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"><style type="text/css" data-react-helmet="true">
:root {
--wt-color-primary-dark-theme: #307FFF;--wt-color-primary-dark-theme-80: rgba(48, 127, 255, 0.8);--wt-color-primary-dark-theme-20: rgba(48, 127, 255, 0.2);--rs-color-primary-dark-theme: #307FFF;--rs-color-primary-dim-dark-theme: #2B6BD2;--rs-color-primary-fog-dark-theme: #203860;--rs-color-primary-t-dim-dark-theme: rgba(48,127,255,0.8);--rs-color-primary-t-fog-dark-theme: rgba(48,127,255,0.3);--wt-color-primary-light-theme: #307FFF;--wt-color-primary-light-theme-80: rgba(48, 127, 255, 0.8);--wt-color-primary-light-theme-20: rgba(48, 127, 255, 0.2);--rs-color-primary-light-theme: #307FFF;--rs-color-primary-dim-light-theme: #5999FF;--rs-color-primary-fog-light-theme: #D6E5FF;--rs-color-primary-t-dim-light-theme: rgba(48,127,255,0.8);--rs-color-primary-t-fog-light-theme: rgba(48,127,255,0.2)
}
</style></head><body data-id="threading_model" data-main-title="Threading Model" data-article-props="{"seeAlsoStyle":"links"}" data-template="article" data-breadcrumbs="Base Platform///fundamentals.md|Fundamentals" data-edit-url="https://github.com/JetBrains/intellij-sdk-docs/edit/main/topics/basics/architectural_overview/threading_model.md" data-initial="/docs/intellij/threading-model.html" class="app-is-rendered jetbrains-cookies-banner-lock-scroll"><!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5P98" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
<script src="https://resources.jetbrains.com/writerside/apidoc/6.10.0-b518/app.js"></script><script type="text/javascript" id="" charset="">(function(){function n(c){c=c.indexOf("?")===-1?c+"?":c+"\x26";for(var d=[],a=0;a<e.length;a++)if(l(e[a])){var b=e[a];e[a].startsWith("utm_")||e[a]=="gclid"||(b="gutm_"+b);d.push(b+"\x3d"+l(e[a]))}if(d.length===0)if(b="last_utm_parameters",a="|",d="utm_source utm_medium utm_campaign utm_term utm_content gclid".split(" "),b=(b=document.cookie.match(new RegExp("(?:^|; )"+b.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g,"\\$1")+"\x3d([^;]*)")))?b[1]:void 0){a=b.split(a);b=[];for(var g=0;g<a.length;g++)a[g]!==
"undefined"&&b.push(d[g]+"\x3d"+a[g]);d=b}else d=[];return c+d.join("\x26")}function l(c){if(c=(new RegExp("[?\x26]"+encodeURIComponent(c)+"\x3d([^\x26]*)")).exec(window.location.search))return decodeURIComponent(c[1])}for(var m=["hyperskill.org"],e="utm_medium utm_source utm_campaign utm_content utm_term medium source campaign content gclid".split(" "),h=document.querySelectorAll("a"),f=0;f<h.length;f++)for(var k=0;k<m.length;k++)h[f].href.indexOf(m[k])>-1&&h[f].href.indexOf("#")===-1&&(h[f].href=
n(h[f].href))})();</script><script type="text/javascript" id="" charset="">var separator="|",firstCookieName="first_utm_parameters",lastCookieName="last_utm_parameters",cookieValue="",undefinedCookieValue=("undefined"+separator).repeat(2)+"undefined",undefinedCookieValueExtended=("undefined"+separator).repeat(5)+"undefined";function getCookie(b){return(b=document.cookie.match(new RegExp("(?:^|; )"+b.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g,"\\$1")+"\x3d([^;]*)")))?b[1]:void 0}
function setCookie(b,a){var d=31104E6,c=new Date,e=c.getTime();c.setTime(e+d);c=c.toUTCString();document.cookie=b+"\x3d"+a+"; SameSite\x3dNone; Secure; expires\x3d"+c+"; path\x3d/; domain\x3d."+stripSubdomain(location.hostname)}function stripSubdomain(b){var a=b.split(".");return 3<=a.length?(a.shift(),a.join(".")):b}
function getReferrerParameters(){try{var b=new URL(document.referrer),a=b.hostname;a=a.replace(/^www\./i,"");var d=b="referral",c="jetbrains.com jetbrains.ru jetbrains.com.cn pretix.eu kotlinlang.org ktor.io datalore.io talkingkotlin.com jetbrains.dev hyperskill.org teamcity.com kotlinconf.com jetbrains.space youtrack.pro qodana.cloud grazie.ai checkoutshopper-live.adyen.com".split(" ");if(c.some(function(e){return-1!==a.indexOf(e)}))return"undefined|undefined|undefined|undefined|undefined|undefined";
if((a.includes("baidu")||a.includes("bing")||a.includes("google"))&&!a.includes("account")){if(a=a.substring(0,a.indexOf(".")),d=b="organic","accounts"==a||"cn"==a||"com"==a||"m"==a)return}else(a.includes("baidu")||a.includes("bing")||a.includes("google"))&&a.includes("account")&&(d=b=a="undefined");return a+"|"+b+"|"+d+"|undefined|undefined|undefined"}catch(e){return"undefined|undefined|undefined|undefined|undefined|undefined"}}
function getQueryParam(b){var a=window.location.search.replaceAll("+","%2b");a=new URLSearchParams(a);return(b=a.get(b))?b.replaceAll("%2b","+"):void 0}cookieValue=getQueryParam("utm_source")||getQueryParam("utm_medium")||getQueryParam("utm_campaign")?getQueryParam("utm_source")+separator+getQueryParam("utm_medium")+separator+getQueryParam("utm_campaign"):getQueryParam("source")+separator+getQueryParam("medium")+separator+getQueryParam("campaign");
cookieValue=getQueryParam("utm_term")?cookieValue+separator+getQueryParam("utm_term"):getQueryParam("keyword")?cookieValue+separator+getQueryParam("keyword"):cookieValue+separator+getQueryParam("term");cookieValue=getQueryParam("utm_content")?cookieValue+separator+getQueryParam("utm_content"):cookieValue+separator+getQueryParam("content");cookieValue=getQueryParam("gclid")?cookieValue+separator+getQueryParam("gclid"):cookieValue+separator+getQueryParam("msclkid");
cookieValue=cookieValue.replace(/\s|,|;/g,"_");cookieValue=cookieValue.substring(0,2E3);
if(cookieValue!==undefinedCookieValueExtended){var first_cookie_value=getCookie(firstCookieName);first_cookie_value&&first_cookie_value!==undefinedCookieValue&&first_cookie_value!==undefinedCookieValueExtended||setCookie(firstCookieName,cookieValue);setCookie(lastCookieName,cookieValue)}else cookieValue=getReferrerParameters(),cookieValue!=undefinedCookieValueExtended&&((first_cookie_value=getCookie(firstCookieName))&&first_cookie_value!==undefinedCookieValue&&first_cookie_value!==undefinedCookieValueExtended||
setCookie(firstCookieName,cookieValue),setCookie(lastCookieName,cookieValue));</script><iframe height="0" width="0" style="display: none; visibility: hidden;"></iframe><div id="webhelp-root"><div class="layout layout--page layout--rows app" data-test="app"><header class="app__header"><div class="layout layout--container layout--unlimited" data-test="layout"><div class="wh-header" data-test="header"><button data-test="header-hamburger" type="button" class="_main_joawza_17 _modeClear_joawza_434 _sizeM_joawza_99 _alignIconLeft_joawza_77 _dark_joawza_62 _withIcon_joawza_119 _withoutText_joawza_113 wh-header__burger"><svg viewBox="0 0 24 24" data-test="icon-hamburger" class="wt-icon wt-icon_size_s _icon_joawza_525"><path d="M4 5h16v2H4zm0 6h16v2H4zm0 6h16v2H4z"></path></svg></button><a href="https://plugins.jetbrains.com/docs/intellij/welcome.html" data-test="external-link " rel="" class="wh-header__link"><img src="https://resources.jetbrains.com/storage/logos/web/jetbrains/jetbrains-particle.svg" alt="IntelliJ Platform Plugin SDK logo" class="wh-header__product-logo wh-header__product-logo--custom" data-test="product-logo"></a><div class="wh-header__product-name" data-test="header-product">IntelliJ Platform Plugin SDK</div> <div class="wh-header__divider"></div><a data-test="button" href="https://jb.gg/ipe" type="button" class="_main_joawza_17 _modeClassic_joawza_135 _sizeM_joawza_99 _alignIconLeft_joawza_77 _dark_joawza_62 wh-header__download">IntelliJ Platform Explorer</a><button data-test="search-button" title="Search" type="button" class="_main_joawza_17 _modeClear_joawza_434 _sizeM_joawza_99 _alignIconLeft_joawza_77 _dark_joawza_62 _withIcon_joawza_119 _withoutText_joawza_113 wh-header__search-button"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_m _icon_joawza_525"><path d="M2.293 10a6.99 6.99 0 0 0 11.187 5.6l6.106 6.107L21 20.293l-6.106-6.106A6.997 6.997 0 1 0 2.293 10zm2 0a5 5 0 1 1 5 5 5 5 0 0 1-5-5z"></path></svg></button></div></div></header><div class="layout layout--container" data-test="layout"><div class="app__sub-header"></div></div><div class="layout layout--columns layout--grow" data-test="layout"><nav class="layout app__sidebar" data-test="app__sidebar"><div class="layout layout--scroll-container app__nav" data-test="scroller"><div class="layout layout--scroll-element" data-test="layout"><ul class="toc app__virtual-toc-mobile" data-test="virtual-toc"><li data-test="virtual-toc-header" class="toc__virtual-toc-header"><div class="toc-item toc-item--selected toc-item--theme-light" to="" data-test="toc-item--selected" style="padding-left: 16px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--opened toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> On this page</div></li><li data-toc-scroll="threading_model" class="toc-node toc-node--selected toc-node--theme-light" data-test="toc-node--selected"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html" style="padding-left: 0px;"> Threading Model</a></li><li data-toc-scroll="read-write-lock" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#read-write-lock" style="padding-left: 0px;"> Read-Write Lock</a></li><li data-toc-scroll="locks-and-edt" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#locks-and-edt" style="padding-left: 16px;"> Locks and EDT</a></li><li data-toc-scroll="accessing-data" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#accessing-data" style="padding-left: 0px;"> Accessing Data</a></li><li data-toc-scroll="read-actions" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#read-actions" style="padding-left: 16px;"> Read Actions</a></li><li data-toc-scroll="write-actions" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#write-actions" style="padding-left: 16px;"> Write Actions</a></li><li data-toc-scroll="invoking-operations-on-edt-and-modality" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#invoking-operations-on-edt-and-modality" style="padding-left: 0px;"> Invoking Operations on EDT and Modality</a></li><li data-toc-scroll="read-action-cancellability" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#read-action-cancellability" style="padding-left: 0px;"> Read Action Cancellability</a></li><li data-toc-scroll="cancellable-read-actions-api" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#cancellable-read-actions-api" style="padding-left: 16px;"> Cancellable Read Actions API</a></li><li data-toc-scroll="avoiding-ui-freezes" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#avoiding-ui-freezes" style="padding-left: 0px;"> Avoiding UI Freezes</a></li><li data-toc-scroll="don-t-perform-long-operations-on-edt" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#don-t-perform-long-operations-on-edt" style="padding-left: 16px;"> Don't Perform Long Operations on EDT</a></li><li data-toc-scroll="event-listeners" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#event-listeners" style="padding-left: 16px;"> Event Listeners</a></li><li data-toc-scroll="vfs-events" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#vfs-events" style="padding-left: 16px;"> VFS Events</a></li><li data-toc-scroll="faq" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#faq" style="padding-left: 0px;"> FAQ</a></li><li data-toc-scroll="how-to-check-whether-the-current-thread-is-the-edtui-thread" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#how-to-check-whether-the-current-thread-is-the-edtui-thread" style="padding-left: 16px;"> How to check whether the current thread is the EDT/UI thread?</a></li><li data-toc-scroll="why-write-actions-are-currently-allowed-only-on-edt" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#why-write-actions-are-currently-allowed-only-on-edt" style="padding-left: 16px;"> Why write actions are currently allowed only on EDT?</a></li><li data-toc-scroll="why-can-write-intent-lock-be-acquired-from-any-thread-but-write-lock-only-from-edt" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#why-can-write-intent-lock-be-acquired-from-any-thread-but-write-lock-only-from-edt" style="padding-left: 16px;"> Why can write intent lock be acquired from any thread but write lock only from EDT?</a></li></ul><div class="layout layout--container" data-test="layout"><div class="app__virtual-toc-divider"></div></div></div><div class="layout layout--scroll-element" data-test="layout"><ul class="toc toc--theme-light app__toc" data-test="toc"><li data-toc-scroll="welcome"><a data-test="internal-link toc-item" rel="" class="toc-item toc-item--theme-light" href="welcome.html" style="padding-left: 16px;"> Home</a></li><li data-toc-scroll="wde4hg_3"><div class="toc-item toc-item--theme-light" to="" data-test="toc-item" style="padding-left: 16px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Introduction</div></li><li data-toc-scroll="wde4hg_4"><div class="toc-item toc-item--theme-light" to="" data-test="toc-item" style="padding-left: 16px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Plugins</div></li><li data-toc-scroll="wde4hg_5"><div class="toc-item toc-item--highlighted toc-item--theme-light" to="" data-test="toc-item" style="padding-left: 16px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--opened toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Base Platform</div></li><li data-toc-scroll="fundamentals"><a data-test="internal-link toc-item" rel="" class="toc-item toc-item--highlighted toc-item--theme-light" href="fundamentals.html" style="padding-left: 32px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--opened toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Fundamentals</a></li><li data-toc-scroll="wde4hg_73"><div class="toc-item toc-item--highlighted toc-item--empty toc-item--theme-light" to="" data-test="toc-item" style="padding-left: 48px;"> Component Model <svg viewBox="0 0 16 16" tabindex="0" class="wt-icon wt-icon_size_xs _trigger_vww70o_81 toc-item__icon toc-item__icon--theme-light"><path d="M15 8a7 7 0 1 1-7-7 7 7 0 0 1 7 7zM6.833 4.5A1.167 1.167 0 1 0 8 3.333 1.167 1.167 0 0 0 6.833 4.5zm-.389 2.753v.778h.778v4.636h1.556V8a.747.747 0 0 0-.747-.747z"></path></svg></div></li><li data-toc-scroll="disposers"><a data-test="internal-link toc-item" rel="" class="toc-item toc-item--highlighted toc-item--theme-light" href="disposers.html" style="padding-left: 48px;"> Disposer and Disposable</a></li><li data-toc-scroll="threading_model"><a data-test="internal-link toc-item--selected" rel="" class="toc-item toc-item--selected toc-item--highlighted toc-item--highlighted-active toc-item--theme-light" href="threading-model.html" style="padding-left: 48px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--opened toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Threading Model</a></li><li data-toc-scroll="background_processes"><a data-test="internal-link toc-item" rel="" class="toc-item toc-item--highlighted toc-item--highlighted-active toc-item--theme-light" href="background-processes.html" style="padding-left: 64px;"> Background Processes</a></li><li data-toc-scroll="kotlin_coroutines"><a data-test="internal-link toc-item" rel="" class="toc-item toc-item--highlighted toc-item--theme-light" href="kotlin-coroutines.html" style="padding-left: 48px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Kotlin Coroutines</a></li><li data-toc-scroll="messaging_infrastructure"><a data-test="internal-link toc-item" rel="" class="toc-item toc-item--highlighted toc-item--theme-light" href="messaging-infrastructure.html" style="padding-left: 48px;"> Messaging Infrastructure</a></li><li data-toc-scroll="wde4hg_78"><div class="toc-item toc-item--highlighted toc-item--empty toc-item--theme-light" to="" data-test="toc-item" style="padding-left: 48px;"> Queries and Query Executors <svg viewBox="0 0 16 16" tabindex="0" class="wt-icon wt-icon_size_xs _trigger_vww70o_81 toc-item__icon toc-item__icon--theme-light"><path d="M15 8a7 7 0 1 1-7-7 7 7 0 0 1 7 7zM6.833 4.5A1.167 1.167 0 1 0 8 3.333 1.167 1.167 0 0 0 6.833 4.5zm-.389 2.753v.778h.778v4.636h1.556V8a.747.747 0 0 0-.747-.747z"></path></svg></div></li><li data-toc-scroll="ide_infrastructure"><a data-test="internal-link toc-item" rel="" class="toc-item toc-item--highlighted toc-item--theme-light" href="ide-infrastructure.html" style="padding-left: 32px;"> IDE Infrastructure</a></li><li data-toc-scroll="user_interface_components"><a data-test="internal-link toc-item" rel="" class="toc-item toc-item--highlighted toc-item--theme-light" href="user-interface-components.html" style="padding-left: 32px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> User Interface Components</a></li><li data-toc-scroll="basic_action_system"><a data-test="internal-link toc-item" rel="" class="toc-item toc-item--highlighted toc-item--theme-light" href="basic-action-system.html" style="padding-left: 32px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Actions</a></li><li data-toc-scroll="persistence"><a data-test="internal-link toc-item" rel="" class="toc-item toc-item--highlighted toc-item--theme-light" href="persistence.html" style="padding-left: 32px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Persistence</a></li><li data-toc-scroll="settings"><a data-test="internal-link toc-item" rel="" class="toc-item toc-item--highlighted toc-item--theme-light" href="settings.html" style="padding-left: 32px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Settings</a></li><li data-toc-scroll="virtual_file_system"><a data-test="internal-link toc-item" rel="" class="toc-item toc-item--highlighted toc-item--theme-light" href="virtual-file-system.html" style="padding-left: 32px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Virtual File System</a></li><li data-toc-scroll="documents"><a data-test="internal-link toc-item" rel="" class="toc-item toc-item--highlighted toc-item--theme-light" href="documents.html" style="padding-left: 32px;"> Documents</a></li><li data-toc-scroll="editors"><a data-test="internal-link toc-item" rel="" class="toc-item toc-item--highlighted toc-item--theme-light" href="editors.html" style="padding-left: 32px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Editors</a></li><li data-toc-scroll="execution"><a data-test="internal-link toc-item" rel="" class="toc-item toc-item--highlighted toc-item--theme-light" href="execution.html" style="padding-left: 32px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Execution</a></li><li data-toc-scroll="vcs_integration_for_plugins"><a data-test="internal-link toc-item" rel="" class="toc-item toc-item--highlighted toc-item--theme-light" href="vcs-integration-for-plugins.html" style="padding-left: 32px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Version Control Systems</a></li><li data-toc-scroll="wde4hg_70"><div class="toc-item toc-item--highlighted toc-item--empty toc-item--theme-light" to="" data-test="toc-item" style="padding-left: 32px;"> Tasks and Contexts <svg viewBox="0 0 16 16" tabindex="0" class="wt-icon wt-icon_size_xs _trigger_vww70o_81 toc-item__icon toc-item__icon--theme-light"><path d="M15 8a7 7 0 1 1-7-7 7 7 0 0 1 7 7zM6.833 4.5A1.167 1.167 0 1 0 8 3.333 1.167 1.167 0 0 0 6.833 4.5zm-.389 2.753v.778h.778v4.636h1.556V8a.747.747 0 0 0-.747-.747z"></path></svg></div></li><li data-toc-scroll="internationalization"><a data-test="internal-link toc-item" rel="" class="toc-item toc-item--highlighted toc-item--theme-light" href="internationalization.html" style="padding-left: 32px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Internationalization</a></li><li data-toc-scroll="wde4hg_72"><div class="toc-item toc-item--highlighted toc-item--empty toc-item--theme-light" to="" data-test="toc-item" style="padding-left: 32px;"> Diagrams <svg viewBox="0 0 16 16" tabindex="0" class="wt-icon wt-icon_size_xs _trigger_vww70o_81 toc-item__icon toc-item__icon--theme-light"><path d="M15 8a7 7 0 1 1-7-7 7 7 0 0 1 7 7zM6.833 4.5A1.167 1.167 0 1 0 8 3.333 1.167 1.167 0 0 0 6.833 4.5zm-.389 2.753v.778h.778v4.636h1.556V8a.747.747 0 0 0-.747-.747z"></path></svg></div></li><li data-toc-scroll="wde4hg_6"><div class="toc-item toc-item--theme-light" to="" data-test="toc-item" style="padding-left: 16px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Project Structure</div></li><li data-toc-scroll="wde4hg_7"><div class="toc-item toc-item--theme-light" to="" data-test="toc-item" style="padding-left: 16px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> PSI</div></li><li data-toc-scroll="wde4hg_8"><div class="toc-item toc-item--theme-light" to="" data-test="toc-item" style="padding-left: 16px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Features</div></li><li data-toc-scroll="wde4hg_9"><div class="toc-item toc-item--theme-light" to="" data-test="toc-item" style="padding-left: 16px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Testing</div></li><li data-toc-scroll="wde4hg_10"><div class="toc-item toc-item--theme-light" to="" data-test="toc-item" style="padding-left: 16px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Custom Languages</div></li><li data-toc-scroll="wde4hg_11"><div class="toc-item toc-item--theme-light" to="" data-test="toc-item" style="padding-left: 16px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Product Specific</div></li><li data-toc-scroll="wde4hg_12"><div class="toc-item toc-item--theme-light" to="" data-test="toc-item" style="padding-left: 16px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Custom IDEs</div></li><li data-toc-scroll="wde4hg_13"><div class="toc-item toc-item--theme-light" to="" data-test="toc-item" style="padding-left: 16px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Themes</div></li><li data-toc-scroll="wde4hg_14"><div class="toc-item toc-item--theme-light" to="" data-test="toc-item" style="padding-left: 16px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Resources</div></li><li data-toc-scroll="wde4hg_15"><div class="toc-item toc-item--theme-light" to="" data-test="toc-item" style="padding-left: 16px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> API and Compatibility</div></li><li data-toc-scroll="wde4hg_16"><div class="toc-item toc-item--theme-light" to="" data-test="toc-item" style="padding-left: 16px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> Tooling</div></li><li data-toc-scroll="ui_guidelines_welcome"><a data-test="internal-link toc-item" rel="" class="toc-item toc-item--theme-light" href="ui-guidelines-welcome.html" style="padding-left: 16px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> UI Guidelines</a></li></ul></div></div></nav><div class="layout layout--rows layout--scroll-container layout--grow" data-test="scroller"><div class="layout layout--container-content layout--columns layout--scroll-element layout--grow" data-test="layout"><article class="layout layout--grow app__article" data-test="app__article"><div class="app__breadcrumbs"><ol class="breadcrumb" data-test="breadcrumb-navigation" itemscope="" itemtype="https://schema.org/BreadcrumbList"><li class="breadcrumb__item" itemprop="itemListElement" itemscope="" itemtype="https://schema.org/ListItem"><div class="breadcrumb__title"><span itemprop="name"><a class="breadcrumb__empty-link" href="#0" itemprop="item">Base Platform</a></span></div><meta itemprop="position" content="0"></li><li class="breadcrumb__item" itemprop="itemListElement" itemscope="" itemtype="https://schema.org/ListItem"><div class="breadcrumb__title breadcrumb__title--link"><span itemprop="name"><a data-test="internal-link breadcrumb-link" rel="" class="link breadcrumb__link" itemprop="item" href="fundamentals.html">Fundamentals</a></span></div><meta itemprop="position" content="1"></li><li class="breadcrumb__item breadcrumb__item--last" itemprop="itemListElement" itemscope="" itemtype="https://schema.org/ListItem"><div class="breadcrumb__title breadcrumb__title--link"><span itemprop="name"><a class="breadcrumb__empty-link" href="#0" itemprop="item">Threading Model</a></span></div><meta itemprop="position" content="2"></li></ol></div><div class="article text2 " data-test="article"><h1 data-toc="threading_model" id="threading_model.md" class="article__h1"><span class="title"><span class="title__content">Threading Model</span></span></h1><span class="sub-title sub-title--related-h1"><span class="sub-title__edit-info"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_m sub-title__editing-icon"><path d="m20.9 12.2a8.94 8.94 0 0 1 -6.4 8.6.39176.39176 0 0 1 -.4-.4v-3a1.58066 1.58066 0 0 0 -.5-1.2 3.7342 3.7342 0 0 0 3.9-3.4 4.24447 4.24447 0 0 0 -.9-3.5 2.8554 2.8554 0 0 0 -.2-2.4 7.23943 7.23943 0 0 0 -2.4.9 8.21667 8.21667 0 0 0 -4.4 0 4.61924 4.61924 0 0 0 -2.3-.9h-.1a2.74943 2.74943 0 0 0 -.2 2.4 4.07472 4.07472 0 0 0 -.9 3.5 3.81064 3.81064 0 0 0 3.9 3.4 1.08192 1.08192 0 0 0 -.4.6 2.63862 2.63862 0 0 0 -.1.7 1.94273 1.94273 0 0 1 -2.2-.5c-.5-.8-.9-1.2-1.4-1.3s-.6.2-.6.2a1.00419 1.00419 0 0 0 .5.6 1.69523 1.69523 0 0 1 .8 1 1.82656 1.82656 0 0 0 1.2 1.2 3.9156 3.9156 0 0 0 1.9 0v1.7a.29725.29725 0 0 1 -.4.3 8.82071 8.82071 0 0 1 -6.3-8.5 8.95014 8.95014 0 0 1 17.9 0z"></path></svg><a href="https://github.com/JetBrains/intellij-sdk-docs/edit/main/topics/basics/architectural_overview/threading_model.md" data-test="external-link edit-page-link" rel="" class="link link--external sub-title__editing-link">Edit page</a><span>Last modified: 28 November 2024</span></span></span><blockquote class="prompt h1-related" data-test-id="pkD4f2ENpHXbTJOh6hhuj"><h3 class="a11y-title">tip</h3><div class="prompt__wrapper prompt__wrapper--type-tip" data-test="prompt"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_m prompt__icon"><circle cx="12.042" cy="4" r="2"></circle><path d="M18.339 7a6.982 6.982 0 0 0-6.3 4 6.982 6.982 0 0 0-6.3-4H3v10h2.739a6.983 6.983 0 0 1 6.3 4 6.582 6.582 0 0 1 6-4.033h2.994L21 7z"></path></svg><div class="prompt__content"><p id="z7olnq5_15" class="article__p child">It is highly recommended that readers unfamiliar with Java threads go through the official <a href="https://docs.oracle.com/javase/tutorial/essential/concurrency/index.html" data-test="external-link " rel="" class="link link--external" id="z7olnq5_16">Java Concurrency</a> tutorial before reading this section.</p></div></div></blockquote><p id="z7olnq5_5" class="article__p h1-related">The IntelliJ Platform is a highly concurrent environment. Code is executed in many threads simultaneously. In general, as in a regular <a href="https://docs.oracle.com/javase%2Ftutorial%2Fuiswing%2F%2F/index.html" data-test="external-link " rel="" class="link link--external" id="z7olnq5_17">Swing</a> application, threads can be categorized into two main groups:</p><ul class="article__list list _bullet h1-related" id="z7olnq5_6"><li class="list__item" id="z7olnq5_18"><p class="article__p child"><a href="https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html" data-test="external-link " rel="" class="link link--external" id="z7olnq5_20">Event Dispatch Thread</a> (EDT) – also known as the UI thread. Its main purpose is handling UI events (such as reacting to clicking a button or updating the UI), but the platform uses it also for writing data. EDT executes events taken from the Event Queue. Operations performed on EDT must be as fast as possible to not block other events in the queue and freeze the UI. There is only one EDT in the running application.</p></li><li class="list__item" id="z7olnq5_19"><p class="article__p child">background threads (BGT) – used for performing long-running and costly operations, or background tasks</p></li></ul><p id="z7olnq5_7" class="article__p h1-related">It is possible to switch between BGT and EDT in both directions. Operations can be scheduled to execute on EDT from BGT (and EDT) with <code class="code" id="z7olnq5_21">invokeLater()</code> methods (see the rest of this page for details). Executing on BGT from EDT can be achieved with <a data-test="internal-link link-with-popover" rel="" class="link" id="z7olnq5_22" href="background-processes.html">background processes</a>.</p><blockquote class="prompt h1-related" data-test-id="VynwFwydSQWvj7ro59LcF"><h3 class="a11y-title">warning</h3><div class="prompt__wrapper prompt__wrapper--type-warning" data-test="prompt"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_m prompt__icon"><path d="M12.946 3.552L21.52 18.4c.424.735.33 1.6-.519 1.6H3.855c-.85 0-1.817-.865-1.392-1.6l8.573-14.848a1.103 1.103 0 0 1 1.91 0zm.545 12.948a1.5 1.5 0 1 0-1.5 1.5 1.5 1.5 0 0 0 1.5-1.5zM13 8h-2v5h2z"></path></svg><div class="prompt__content"><p id="z7olnq5_23" class="article__p child">Plugins targeting versions 2024.1+ should use <a data-test="internal-link link-with-popover" rel="" class="link" id="z7olnq5_24" href="coroutine-dispatchers.html">coroutine dispatchers</a> for switching between threads.</p></div></div></blockquote><section class="chapter h1-related"><h2 id="read-write-lock" data-toc="read-write-lock" class="article__h2"><span class="title"><span class="title__content">Read-Write Lock</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#read-write-lock"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#read-write-lock"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_s permalink__icon permalink__icon--size-s"><path d="M21.207 4.793a4.536 4.536 0 0 0-6.414 0l-4.5 4.5 1.414 1.414 4.5-4.5a2.536 2.536 0 0 1 3.586 3.586l-4.5 4.5 1.414 1.414 4.5-4.5a4.536 4.536 0 0 0 0-6.414z"></path><path d="M8.328 16.258a2.536 2.536 0 1 1-3.586-3.586l4.5-4.5-1.414-1.414-4.5 4.5a4.535 4.535 0 0 0 6.414 6.414l4.5-4.5-1.414-1.414z"></path></svg></span></a></span></h2><p id="z7olnq5_25" class="article__p h2-related">The IntelliJ Platform data structures (such as <a data-test="internal-link link-with-popover" rel="" class="link" id="z7olnq5_35" href="psi.html">Program Structure Interface</a>, <a data-test="internal-link link-with-popover" rel="" class="link" id="z7olnq5_36" href="virtual-file-system.html">Virtual File System</a>, or <a data-test="internal-link link-with-popover" rel="" class="link" id="z7olnq5_37" href="project-model.html">Project root model</a>) aren't thread-safe. Accessing them requires a synchronization mechanism ensuring that all threads see the data in a consistent and up-to-date state. This is implemented with a single application-wide <a href="https://w.wiki/7dBy" data-test="external-link " rel="" class="link link--external" id="z7olnq5_38">read-write (RW) lock</a> that must be acquired by threads requiring reading or writing to data models.</p><p id="z7olnq5_26" class="article__p h2-related">If a thread requires accessing a data model, it must acquire one of the locks:</p><div class="table h2-related"><div class="table__wrapper table__wrapper--wide table__wrapper--without-scroll"><table class="table__content table__content--wide" id="z7olnq5_27"><thead class="table__thead undefined"><tr class="table__tr ijRowHead" id="z7olnq5_39"><th class="table__th undefined" id="z7olnq5_43" width="33%"><p class="article__p">Read Lock</p></th><th class="table__th undefined" id="z7olnq5_44" width="33%"><p class="article__p">Write Intent Lock</p></th><th class="table__th undefined" id="z7olnq5_45" width="33%"><p class="article__p">Write Lock</p></th></tr></thead><tbody class="table__tbody undefined"><tr class="table__tr undefined" id="z7olnq5_40"><td class="table__td undefined" id="z7olnq5_46"><p class="article__p child">Allows a thread for reading data.</p></td><td class="table__td undefined" id="z7olnq5_47"><p class="article__p child">Allows a thread for reading data and potentially upgrade to the write lock.</p></td><td class="table__td undefined" id="z7olnq5_48"><p class="article__p child">Allows a thread for reading and writing data.</p></td></tr><tr class="table__tr undefined" id="z7olnq5_41"><td class="table__td undefined" id="z7olnq5_49"><p class="article__p child">Can be acquired from any thread concurrently with other read locks and write intent lock.</p></td><td class="table__td undefined" id="z7olnq5_50"><p class="article__p child">Can be acquired from any thread concurrently with read locks.</p></td><td class="table__td undefined" id="z7olnq5_51"><p class="article__p child">Can be acquired only from EDT concurrently with a write intent lock acquired on EDT.</p></td></tr><tr class="table__tr undefined" id="z7olnq5_42"><td class="table__td undefined" id="z7olnq5_52"><p class="article__p child">Can't be acquired if write lock is held on another thread.</p></td><td class="table__td undefined" id="z7olnq5_53"><p class="article__p child">Can't be acquired if another write intent lock or write lock is held on another thread.</p></td><td class="table__td undefined" id="z7olnq5_54"><p class="article__p child">Can't be acquired if any other lock is held on another thread.</p></td></tr></tbody></table></div></div><blockquote class="prompt h2-related" data-test-id="qx0CcwztghLd_BHrIhq_f"><h3 class="a11y-title">tip</h3><div class="prompt__wrapper prompt__wrapper--type-tip" data-test="prompt"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_m prompt__icon"><circle cx="12.042" cy="4" r="2"></circle><path d="M18.339 7a6.982 6.982 0 0 0-6.3 4 6.982 6.982 0 0 0-6.3-4H3v10h2.739a6.983 6.983 0 0 1 6.3 4 6.582 6.582 0 0 1 6-4.033h2.994L21 7z"></path></svg><div class="prompt__content"><p id="z7olnq5_55" class="article__p child">See the <a data-test="internal-link " rel="" class="link" id="z7olnq5_56" href="/docs/intellij/threading-model.html#why-can-write-intent-lock-be-acquired-from-any-thread-but-write-lock-only-from-edt">reasons</a> for allowing to acquire write intent lock from any thread and the write lock only from EDT.</p></div></div></blockquote><p id="z7olnq5_29" class="article__p h2-related">The following table shows compatibility between locks in a simplified form:</p><div class="table table--left-header h2-related"><div class="table__wrapper table__wrapper--wide table__wrapper--without-scroll"><table class="table__content table__content--wide" id="z7olnq5_30"><thead class="table__thead undefined"><tr class="table__tr ijRowHead" id="z7olnq5_57"><th class="table__th undefined" id="z7olnq5_61" width="25%"></th><th class="table__th undefined" id="z7olnq5_62" width="25%"><p class="article__p">Read Lock</p></th><th class="table__th undefined" id="z7olnq5_63" width="25%"><p class="article__p">Write Intent Lock</p></th><th class="table__th undefined" id="z7olnq5_64" width="25%"><p class="article__p">Write Lock</p></th></tr></thead><tbody class="table__tbody undefined"><tr class="table__tr undefined" id="z7olnq5_58"><th class="table__th undefined" id="z7olnq5_65"><p class="article__p">Read Lock</p></th><td class="table__td undefined" id="z7olnq5_66"><p class="article__p child"><img src="images/green_checkmark.svg" class="article__img inline-icon-" alt="+" width="16" title="+" id="z7olnq5_69" height="16"></p></td><td class="table__td undefined" id="z7olnq5_67"><p class="article__p child"><img src="images/green_checkmark.svg" class="article__img inline-icon-" alt="+" width="16" title="+" id="z7olnq5_70" height="16"></p></td><td class="table__td undefined" id="z7olnq5_68"><p class="article__p child"><img src="images/red_cross.svg" class="article__img inline-icon-" alt="-" width="16" title="-" id="z7olnq5_71" height="16"></p></td></tr><tr class="table__tr undefined" id="z7olnq5_59"><th class="table__th undefined" id="z7olnq5_72"><p class="article__p">Write Intent Lock</p></th><td class="table__td undefined" id="z7olnq5_73"><p class="article__p child"><img src="images/green_checkmark.svg" class="article__img inline-icon-" alt="+" width="16" title="+" id="z7olnq5_76" height="16"></p></td><td class="table__td undefined" id="z7olnq5_74"><p class="article__p child"><img src="images/red_cross.svg" class="article__img inline-icon-" alt="-" width="16" title="-" id="z7olnq5_77" height="16"></p></td><td class="table__td undefined" id="z7olnq5_75"><p class="article__p child"><img src="images/red_cross.svg" class="article__img inline-icon-" alt="-" width="16" title="-" id="z7olnq5_78" height="16"></p></td></tr><tr class="table__tr undefined" id="z7olnq5_60"><th class="table__th undefined" id="z7olnq5_79"><p class="article__p">Write Lock</p></th><td class="table__td undefined" id="z7olnq5_80"><p class="article__p child"><img src="images/red_cross.svg" class="article__img inline-icon-" alt="-" width="16" title="-" id="z7olnq5_83" height="16"></p></td><td class="table__td undefined" id="z7olnq5_81"><p class="article__p child"><img src="images/red_cross.svg" class="article__img inline-icon-" alt="-" width="16" title="-" id="z7olnq5_84" height="16"></p></td><td class="table__td undefined" id="z7olnq5_82"><p class="article__p child"><img src="images/red_cross.svg" class="article__img inline-icon-" alt="-" width="16" title="-" id="z7olnq5_85" height="16"></p></td></tr></tbody></table></div></div><p id="z7olnq5_31" class="article__p h2-related">The described lock characteristics conclude the following:</p><ul class="article__list list _bullet h2-related" id="z7olnq5_32"><li class="list__item" id="z7olnq5_86"><p class="article__p child">multiple threads can read data at the same time</p></li><li class="list__item" id="z7olnq5_87"><p class="article__p child">once a thread acquires the write lock, no other threads can read or write data</p></li></ul><p id="z7olnq5_33" class="article__p h2-related">Acquiring and releasing locks explicitly in code would be verbose and error-prone and must never be done by plugins. The IntelliJ Platform enables write intent lock implicitly on EDT (see <a data-test="internal-link " rel="" class="link" id="z7olnq5_88" href="/docs/intellij/threading-model.html#locks-and-edt">Locks and EDT</a> for details) and provides an <a data-test="internal-link " rel="" class="link" id="z7olnq5_89" href="/docs/intellij/threading-model.html#accessing-data">API for accessing data under read or write locks</a>.</p><section class="chapter h2-related"><h3 id="locks-and-edt" data-toc="locks-and-edt" class="article__h3"><span class="title"><span class="title__content">Locks and EDT</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#locks-and-edt"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#locks-and-edt"><svg viewBox="0 0 16 16" class="wt-icon wt-icon_size_xs permalink__icon permalink__icon--size-xs"><path d="M14.094 3.801a3.093 3.093 0 0 0-4.373 0L6.653 6.87l.964.964 3.068-3.069A1.729 1.729 0 0 1 13.13 7.21l-3.068 3.069.964.964 3.068-3.068a3.093 3.093 0 0 0 0-4.374z"></path><path d="M5.313 11.618a1.729 1.729 0 0 1-2.445-2.445l3.068-3.068-.964-.964-3.068 3.068a3.092 3.092 0 0 0 4.373 4.374l3.069-3.069-.965-.964z"></path></svg></span></a></span></h3><p id="z7olnq5_90" class="article__p h3-related">Although acquiring all types of locks can be, in theory, done from any threads, the platform implicitly acquires write intent lock and allows acquiring the write lock only on EDT. It means that <span class="control" id="z7olnq5_94">writing data can be done only on EDT</span>.</p><blockquote class="prompt h3-related" data-test-id="NGltYLZjsgv4qGr1Jl49T"><h3 class="a11y-title">tip</h3><div class="prompt__wrapper prompt__wrapper--type-tip" data-test="prompt"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_m prompt__icon"><circle cx="12.042" cy="4" r="2"></circle><path d="M18.339 7a6.982 6.982 0 0 0-6.3 4 6.982 6.982 0 0 0-6.3-4H3v10h2.739a6.983 6.983 0 0 1 6.3 4 6.582 6.582 0 0 1 6-4.033h2.994L21 7z"></path></svg><div class="prompt__content"><p id="z7olnq5_95" class="article__p child">It is known that writing data only on EDT has negative consequences of potentially freezing the UI. There is an in-progress effort to <a href="https://youtrack.jetbrains.com/issue/IJPL-53" data-test="external-link " rel="" class="link link--external" id="z7olnq5_96">allow writing data from any thread</a>. See the <a data-test="internal-link " rel="" class="link" id="z7olnq5_97" href="/docs/intellij/threading-model.html#why-write-actions-are-currently-allowed-only-on-edt">historical reason</a> for this behavior in the current platform versions.</p></div></div></blockquote><p id="z7olnq5_92" class="article__p h3-related">The scope of implicitly acquiring the write intent lock on EDT differs depending on the platform version:</p><div data-test="tab-list-wrapper"><div class="_wrapper_edyv3p_4 _light_edyv3p_82"><div class="_arrow_edyv3p_39 _arrowLeft_edyv3p_99" data-test="scrollable-list-arrow-left-wrapper" style="height: 100%;"><div data-test="scrollable-list-arrow-left" class="_main_g361av_17 _modeClear_g361av_434 _sizeS_g361av_92 _alignIconLeft_g361av_77 _light_g361av_59 _withIcon_g361av_119 _withoutText_g361av_113"><svg viewBox="0 0 24 24" class="_icon_1r3x2p9_3 _sizeM_1r3x2p9_12 _icon_g361av_529"><path d="M15.004 19V5l-8 7 8 7z"></path></svg></div><div class="_arrowShadow_edyv3p_39"></div></div><div class="_scrollable_edyv3p_10"><div class="_tabsContainer_1fcqo6x_13 _light_1fcqo6x_31 _classic_1fcqo6x_31 _sizeM_1fcqo6x_99 _innerOffsetM_1fcqo6x_109 tabs h3-related undefined" data-test="tab-list"><div class="_tab_1fcqo6x_13 _selected_1fcqo6x_141 _short_1fcqo6x_133" role="tab" tabindex="0" data-e2e="tab" data-test="tab tab-selected"><div><div data-test="tab-title" id="z7olnq5_98">2023.3+</div></div></div><div class="_tab_1fcqo6x_13 _short_1fcqo6x_133" role="tab" tabindex="0" data-e2e="tab" data-test="tab"><div><div data-test="tab-title" id="z7olnq5_99">Earlier versions</div></div></div><span class="_indicator_1fcqo6x_19" style="left: 0px; width: 61.1719px;"></span></div></div><div class="_arrow_edyv3p_39 _arrowRight_edyv3p_112" data-test="scrollable-list-arrow-right-wrapper" style="height: 100%;"><div data-test="scrollable-list-arrow-right" class="_main_g361av_17 _modeClear_g361av_434 _sizeS_g361av_92 _alignIconLeft_g361av_77 _light_g361av_59 _withIcon_g361av_119 _withoutText_g361av_113 _arrowButton_edyv3p_126"><svg viewBox="0 0 24 24" class="_icon_1r3x2p9_3 _sizeM_1r3x2p9_12 _icon_g361av_529"><path d="M9.004 19l8-7-8-7v14z"></path></svg></div><div class="_arrowShadow_edyv3p_39"></div></div></div><div data-test="tab-content" class="tabs__content-wrapper"><div class="tabs__content" data-gtm="tab" data-sync-tabs="newThreading" data-title="2023.3+" data-tab-id="z7olnq5_98"><p id="z7olnq5_100" class="article__p child">Write intent lock is acquired automatically when operation is invoked on EDT with <a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/core-api/src/com/intellij/openapi/application/Application.java" data-test="external-link " rel="" class="link link--external" id="z7olnq5_101"><code class="code" id="z7olnq5_102">Application.invokeLater()</code></a>.</p></div></div><div data-test="tab-content" class="tabs__content-wrapper" style="display: none;"><div class="tabs__content" data-gtm="tab" data-sync-tabs="oldThreading" data-title="Earlier versions" data-tab-id="z7olnq5_99"><p id="z7olnq5_103" class="article__p child">Write intent lock is acquired automatically when operation is invoked on EDT with methods such as:</p><ul class="article__list list _bullet child list--nested" id="z7olnq5_104"><li class="list__item" id="z7olnq5_106"><p class="article__p child"><a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/core-api/src/com/intellij/openapi/application/Application.java" data-test="external-link " rel="" class="link link--external" id="z7olnq5_111"><code class="code" id="z7olnq5_112">Application.invokeLater()</code></a>,</p></li><li class="list__item" id="z7olnq5_107"><p class="article__p child"><a href="https://docs.oracle.com/javase/8/docs/api/javax/swing/SwingUtilities.html#invokeLater-java.lang.Runnable-" data-test="external-link " rel="" class="link link--external" id="z7olnq5_113"><code class="code" id="z7olnq5_114">SwingUtilities.invokeLater()</code></a>,</p></li><li class="list__item" id="z7olnq5_108"><p class="article__p child"><a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/util/ui/src/com/intellij/util/ui/UIUtil.java" data-test="external-link " rel="" class="link link--external" id="z7olnq5_115"><code class="code" id="z7olnq5_116">UIUtil.invokeAndWaitIfNeeded()</code></a>,</p></li><li class="list__item" id="z7olnq5_109"><p class="article__p child"><a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/util/src/com/intellij/util/ui/EdtInvocationManager.java" data-test="external-link " rel="" class="link link--external" id="z7olnq5_117"><code class="code" id="z7olnq5_118">EdtInvocationManager.invokeLaterIfNeeded()</code></a>,</p></li><li class="list__item" id="z7olnq5_110"><p class="article__p child">and other similar methods</p></li></ul><p id="z7olnq5_105" class="article__p child">It is recommended to use <code class="code" id="z7olnq5_119">Application.invokeLater()</code> if the operation is supposed to write data. Use other methods for pure UI operations.</p></div></div></div></section></section><section class="chapter h1-related"><h2 id="accessing-data" data-toc="accessing-data" class="article__h2"><span class="title"><span class="title__content">Accessing Data</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#accessing-data"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#accessing-data"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_s permalink__icon permalink__icon--size-s"><path d="M21.207 4.793a4.536 4.536 0 0 0-6.414 0l-4.5 4.5 1.414 1.414 4.5-4.5a2.536 2.536 0 0 1 3.586 3.586l-4.5 4.5 1.414 1.414 4.5-4.5a4.536 4.536 0 0 0 0-6.414z"></path><path d="M8.328 16.258a2.536 2.536 0 1 1-3.586-3.586l4.5-4.5-1.414-1.414-4.5 4.5a4.535 4.535 0 0 0 6.414 6.414l4.5-4.5-1.414-1.414z"></path></svg></span></a></span></h2><p id="z7olnq5_120" class="article__p h2-related">The IntelliJ Platform provides a simple API for accessing data under read or write locks in a form of read and write actions.</p><p id="z7olnq5_121" class="article__p h2-related">Read and write actions allow executing a piece of code under a lock, automatically acquiring it before an action starts, and releasing it after the action is finished.</p><blockquote class="prompt h2-related" data-test-id="XGqTV2oINCYpcq7RjuFew"><h3 class="a11y-title">warning</h3><div class="prompt__wrapper prompt__wrapper--type-warning" data-test="prompt"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_m prompt__icon"><path d="M12.946 3.552L21.52 18.4c.424.735.33 1.6-.519 1.6H3.855c-.85 0-1.817-.865-1.392-1.6l8.573-14.848a1.103 1.103 0 0 1 1.91 0zm.545 12.948a1.5 1.5 0 1 0-1.5 1.5 1.5 1.5 0 0 0 1.5-1.5zM13 8h-2v5h2z"></path></svg><div class="prompt__content"><div class="prompt__title">Minimize Locking Scopes</div><p id="z7olnq5_125" class="article__p child">Always try to wrap only the required operations into read/write actions, minimizing the time of holding locks. If the read operation itself is long, consider using one of <a data-test="internal-link " rel="" class="link" id="z7olnq5_126" href="/docs/intellij/threading-model.html#read-action-cancellability">read action cancellability techniques</a> to avoid blocking the write lock and EDT.</p></div></div></blockquote><section class="chapter h2-related"><h3 id="read-actions" data-toc="read-actions" class="article__h3"><span class="title"><span class="title__content">Read Actions</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#read-actions"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#read-actions"><svg viewBox="0 0 16 16" class="wt-icon wt-icon_size_xs permalink__icon permalink__icon--size-xs"><path d="M14.094 3.801a3.093 3.093 0 0 0-4.373 0L6.653 6.87l.964.964 3.068-3.069A1.729 1.729 0 0 1 13.13 7.21l-3.068 3.069.964.964 3.068-3.068a3.093 3.093 0 0 0 0-4.374z"></path><path d="M5.313 11.618a1.729 1.729 0 0 1-2.445-2.445l3.068-3.068-.964-.964-3.068 3.068a3.092 3.092 0 0 0 4.373 4.374l3.069-3.069-.965-.964z"></path></svg></span></a></span></h3><section class="chapter h3-related"><h4 id="read-actions-api" data-toc="read-actions-api" class="article__h4"><span class="title"><span class="title__content">API</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#read-actions-api"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#read-actions-api"><svg viewBox="0 0 16 16" class="wt-icon wt-icon_size_xs permalink__icon permalink__icon--size-xs"><path d="M14.094 3.801a3.093 3.093 0 0 0-4.373 0L6.653 6.87l.964.964 3.068-3.069A1.729 1.729 0 0 1 13.13 7.21l-3.068 3.069.964.964 3.068-3.068a3.093 3.093 0 0 0 0-4.374z"></path><path d="M5.313 11.618a1.729 1.729 0 0 1-2.445-2.445l3.068-3.068-.964-.964-3.068 3.068a3.092 3.092 0 0 0 4.373 4.374l3.069-3.069-.965-.964z"></path></svg></span></a></span></h4><ul class="article__list list _bullet h4-related" id="z7olnq5_129"><li class="list__item" id="z7olnq5_131"><p id="z7olnq5_132" class="article__p child"><a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/core-api/src/com/intellij/openapi/application/ReadAction.java" data-test="external-link " rel="" class="link link--external" id="z7olnq5_134"><code class="code" id="z7olnq5_137">ReadAction</code></a> <code class="code" id="z7olnq5_135">run()</code> or <code class="code" id="z7olnq5_136">compute()</code>:</p><div data-test="tab-list-wrapper"><div class="_wrapper_edyv3p_4 _light_edyv3p_82"><div class="_arrow_edyv3p_39 _arrowLeft_edyv3p_99" data-test="scrollable-list-arrow-left-wrapper" style="height: 100%;"><div data-test="scrollable-list-arrow-left" class="_main_g361av_17 _modeClear_g361av_434 _sizeS_g361av_92 _alignIconLeft_g361av_77 _light_g361av_59 _withIcon_g361av_119 _withoutText_g361av_113"><svg viewBox="0 0 24 24" class="_icon_1r3x2p9_3 _sizeM_1r3x2p9_12 _icon_g361av_529"><path d="M15.004 19V5l-8 7 8 7z"></path></svg></div><div class="_arrowShadow_edyv3p_39"></div></div><div class="_scrollable_edyv3p_10"><div class="_tabsContainer_1fcqo6x_13 _light_1fcqo6x_31 _classic_1fcqo6x_31 _sizeM_1fcqo6x_99 _innerOffsetM_1fcqo6x_109 tabs tabs--nested child undefined" data-test="tab-list"><div class="_tab_1fcqo6x_13 _selected_1fcqo6x_141 _short_1fcqo6x_133" role="tab" tabindex="0" data-e2e="tab" data-test="tab tab-selected"><div><div data-test="tab-title" id="z7olnq5_138">Kotlin</div></div></div><div class="_tab_1fcqo6x_13 _short_1fcqo6x_133" role="tab" tabindex="0" data-e2e="tab" data-test="tab"><div><div data-test="tab-title" id="z7olnq5_139">Java</div></div></div><span class="_indicator_1fcqo6x_19" style="left: 0px; width: 43.1562px;"></span></div></div><div class="_arrow_edyv3p_39 _arrowRight_edyv3p_112" data-test="scrollable-list-arrow-right-wrapper" style="height: 100%;"><div data-test="scrollable-list-arrow-right" class="_main_g361av_17 _modeClear_g361av_434 _sizeS_g361av_92 _alignIconLeft_g361av_77 _light_g361av_59 _withIcon_g361av_119 _withoutText_g361av_113 _arrowButton_edyv3p_126"><svg viewBox="0 0 24 24" class="_icon_1r3x2p9_3 _sizeM_1r3x2p9_12 _icon_g361av_529"><path d="M9.004 19l8-7-8-7v14z"></path></svg></div><div class="_arrowShadow_edyv3p_39"></div></div></div><div data-test="tab-content" class="tabs__content-wrapper tabs__content-wrapper--nested"><div class="tabs__content" data-gtm="tab" data-sync-tabs="kotlin" data-title="Kotlin" data-tab-id="z7olnq5_138"><div class="code-block__wrapper"><div id="" class="code-block code-block child" data-test="code-block"><pre class="code-block__pre language-kotlin" id="code-IHFCmdd06GM8dp_twLLT4"><code><span class="prism--token prism--keyword">val</span> psiFile <span class="prism--token prism--operator">=</span> ReadAction<span class="prism--token prism--punctuation">.</span>compute<span class="prism--token prism--operator"><</span>PsiFile<span class="prism--token prism--punctuation">,</span> Throwable<span class="prism--token prism--operator">></span> <span class="prism--token prism--punctuation">{</span>
<span class="prism--token prism--comment">// read and return PsiFile</span>
<span class="prism--token prism--punctuation">}</span></code></pre><div class="copy-button__container"><div class="copy-button" data-clipboard-target="#code-IHFCmdd06GM8dp_twLLT4" data-test="copy-button" role="button" tabindex="0"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_l copy-button__icon"><path d="M9 5h10v10H9z"></path><path d="M7 9H5v10h10v-2H7V9z"></path></svg></div></div></div></div></div></div><div data-test="tab-content" class="tabs__content-wrapper tabs__content-wrapper--nested" style="display: none;"><div class="tabs__content" data-gtm="tab" data-sync-tabs="java" data-title="Java" data-tab-id="z7olnq5_139"><div class="code-block__wrapper"><div id="" class="code-block code-block child" data-test="code-block"><pre class="code-block__pre language-java" id="code-U0WsMueQU5isvDwWoTgWc"><code><span class="prism--token prism--class-name">PsiFile</span> psiFile <span class="prism--token prism--operator">=</span> <span class="prism--token prism--class-name">ReadAction</span><span class="prism--token prism--punctuation">.</span><span class="prism--token prism--function">compute</span><span class="prism--token prism--punctuation">(</span><span class="prism--token prism--punctuation">(</span><span class="prism--token prism--punctuation">)</span> <span class="prism--token prism--operator">-></span> <span class="prism--token prism--punctuation">{</span>
<span class="prism--token prism--comment">// read and return PsiFile</span>
<span class="prism--token prism--punctuation">}</span><span class="prism--token prism--punctuation">)</span><span class="prism--token prism--punctuation">;</span></code></pre><div class="copy-button__container"><div class="copy-button" data-clipboard-target="#code-U0WsMueQU5isvDwWoTgWc" data-test="copy-button" role="button" tabindex="0"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_l copy-button__icon"><path d="M9 5h10v10H9z"></path><path d="M7 9H5v10h10v-2H7V9z"></path></svg></div></div></div></div></div></div></div></li></ul><section class="chapter h4-related"><div class="collapse" data-test="collapse-element" data-is-animating="false" data-test-is-animating="false"><div class="collapse__header collapse__title" role="button" tabindex="0" aria-expanded="false" data-test="collapse-header"><h5 id="read-action-alternative-apis" data-toc="read-action-alternative-apis" class="article__h5"><span class="title"><span class="title__content">Alternative APIs</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#read-action-alternative-apis"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#read-action-alternative-apis"><svg viewBox="0 0 16 16" class="wt-icon wt-icon_size_xs permalink__icon permalink__icon--size-xs"><path d="M14.094 3.801a3.093 3.093 0 0 0-4.373 0L6.653 6.87l.964.964 3.068-3.069A1.729 1.729 0 0 1 13.13 7.21l-3.068 3.069.964.964 3.068-3.068a3.093 3.093 0 0 0 0-4.374z"></path><path d="M5.313 11.618a1.729 1.729 0 0 1-2.445-2.445l3.068-3.068-.964-.964-3.068 3.068a3.092 3.092 0 0 0 4.373 4.374l3.069-3.069-.965-.964z"></path></svg></span></a></span></h5><div class="collapse__button" data-test="collapse-button" aria-hidden="true" style="top: -2px;"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_m collapse__icon"><path d="M21 12a9 9 0 1 1-9-9 9 9 0 0 1 9 9zm-4.235-3.351l-1.414-1.414L12 10.585 8.635 7.222 7.221 8.635 10.586 12l-3.257 3.257 1.414 1.414L12 13.414l3.288 3.289 1.415-1.415L13.414 12z"></path></svg></div></div><div class="collapse__body" data-test="collapse-content" aria-hidden="true"><ul class="article__list list _bullet child list--nested" id="z7olnq5_142"><li class="list__item" id="z7olnq5_143"><p id="z7olnq5_145" class="article__p child"><a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/core-api/src/com/intellij/openapi/application/Application.java" data-test="external-link " rel="" class="link link--external" id="z7olnq5_147"><code class="code" id="z7olnq5_148">Application.runReadAction()</code></a>:</p><div data-test="tab-list-wrapper"><div class="_wrapper_edyv3p_4 _light_edyv3p_82"><div class="_arrow_edyv3p_39 _arrowLeft_edyv3p_99" data-test="scrollable-list-arrow-left-wrapper" style="height: 100%;"><div data-test="scrollable-list-arrow-left" class="_main_g361av_17 _modeClear_g361av_434 _sizeS_g361av_92 _alignIconLeft_g361av_77 _light_g361av_59 _withIcon_g361av_119 _withoutText_g361av_113"><svg viewBox="0 0 24 24" class="_icon_1r3x2p9_3 _sizeM_1r3x2p9_12 _icon_g361av_529"><path d="M15.004 19V5l-8 7 8 7z"></path></svg></div><div class="_arrowShadow_edyv3p_39"></div></div><div class="_scrollable_edyv3p_10"><div class="_tabsContainer_1fcqo6x_13 _light_1fcqo6x_31 _classic_1fcqo6x_31 _sizeM_1fcqo6x_99 _innerOffsetM_1fcqo6x_109 tabs tabs--nested child undefined" data-test="tab-list"><div class="_tab_1fcqo6x_13 _selected_1fcqo6x_141 _short_1fcqo6x_133" role="tab" tabindex="0" data-e2e="tab" data-test="tab tab-selected"><div><div data-test="tab-title" id="z7olnq5_149">Kotlin</div></div></div><div class="_tab_1fcqo6x_13 _short_1fcqo6x_133" role="tab" tabindex="0" data-e2e="tab" data-test="tab"><div><div data-test="tab-title" id="z7olnq5_150">Java</div></div></div><span class="_indicator_1fcqo6x_19" style="left: 0px; width: 43.1562px;"></span></div></div><div class="_arrow_edyv3p_39 _arrowRight_edyv3p_112" data-test="scrollable-list-arrow-right-wrapper" style="height: 100%;"><div data-test="scrollable-list-arrow-right" class="_main_g361av_17 _modeClear_g361av_434 _sizeS_g361av_92 _alignIconLeft_g361av_77 _light_g361av_59 _withIcon_g361av_119 _withoutText_g361av_113 _arrowButton_edyv3p_126"><svg viewBox="0 0 24 24" class="_icon_1r3x2p9_3 _sizeM_1r3x2p9_12 _icon_g361av_529"><path d="M9.004 19l8-7-8-7v14z"></path></svg></div><div class="_arrowShadow_edyv3p_39"></div></div></div><div data-test="tab-content" class="tabs__content-wrapper tabs__content-wrapper--nested"><div class="tabs__content" data-gtm="tab" data-sync-tabs="kotlin" data-title="Kotlin" data-tab-id="z7olnq5_149"><div class="code-block__wrapper"><div id="" class="code-block code-block child" data-test="code-block"><pre class="code-block__pre language-kotlin" id="code-DFXUiNvnR9AGCHsPmOyt3"><code><span class="prism--token prism--keyword">val</span> psiFile <span class="prism--token prism--operator">=</span> ApplicationManager<span class="prism--token prism--punctuation">.</span>application<span class="prism--token prism--punctuation">.</span><span class="prism--token prism--function">runReadAction</span> <span class="prism--token prism--punctuation">{</span>
<span class="prism--token prism--comment">// read and return PsiFile</span>
<span class="prism--token prism--punctuation">}</span></code></pre><div class="copy-button__container"><div class="copy-button" data-clipboard-target="#code-DFXUiNvnR9AGCHsPmOyt3" data-test="copy-button" role="button" tabindex="0"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_l copy-button__icon"><path d="M9 5h10v10H9z"></path><path d="M7 9H5v10h10v-2H7V9z"></path></svg></div></div></div></div></div></div><div data-test="tab-content" class="tabs__content-wrapper tabs__content-wrapper--nested" style="display: none;"><div class="tabs__content" data-gtm="tab" data-sync-tabs="java" data-title="Java" data-tab-id="z7olnq5_150"><div class="code-block__wrapper"><div id="" class="code-block code-block child" data-test="code-block"><pre class="code-block__pre language-java" id="code-tHFLUUIDrPsDCNcqA9gTT"><code><span class="prism--token prism--class-name">PsiFile</span> psiFile <span class="prism--token prism--operator">=</span> <span class="prism--token prism--class-name">ApplicationManager</span><span class="prism--token prism--punctuation">.</span><span class="prism--token prism--function">getApplication</span><span class="prism--token prism--punctuation">(</span><span class="prism--token prism--punctuation">)</span>
<span class="prism--token prism--punctuation">.</span><span class="prism--token prism--function">runReadAction</span><span class="prism--token prism--punctuation">(</span><span class="prism--token prism--punctuation">(</span><span class="prism--token prism--class-name">Computable</span><span class="prism--token prism--generics"><span class="prism--token prism--punctuation"><</span><span class="prism--token prism--class-name">PsiFile</span><span class="prism--token prism--punctuation">></span></span><span class="prism--token prism--punctuation">)</span><span class="prism--token prism--punctuation">(</span><span class="prism--token prism--punctuation">)</span> <span class="prism--token prism--operator">-></span> <span class="prism--token prism--punctuation">{</span>
<span class="prism--token prism--comment">// read and return PsiFile</span>
<span class="prism--token prism--punctuation">}</span><span class="prism--token prism--punctuation">)</span><span class="prism--token prism--punctuation">;</span></code></pre><div class="copy-button__container"><div class="copy-button" data-clipboard-target="#code-tHFLUUIDrPsDCNcqA9gTT" data-test="copy-button" role="button" tabindex="0"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_l copy-button__icon"><path d="M9 5h10v10H9z"></path><path d="M7 9H5v10h10v-2H7V9z"></path></svg></div></div></div></div></div></div></div><p class="article__p child"> Note that this API is considered low-level and should be avoided.</p></li><li class="list__item" id="z7olnq5_144"><p id="z7olnq5_153" class="article__p child">Kotlin <a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/core-api/src/com/intellij/openapi/application/actions.kt" data-test="external-link " rel="" class="link link--external" id="z7olnq5_156"><code class="code" id="z7olnq5_157">runReadAction()</code></a>:</p><div class="code-block__wrapper"><div id="" class="code-block child in-flow" data-test="code-block"><pre class="code-block__pre language-kotlin" id="code-80ByD7lSAg_SJ3Ads3Aqv"><code><span class="prism--token prism--keyword">val</span> psiFile <span class="prism--token prism--operator">=</span> runReadAction <span class="prism--token prism--punctuation">{</span>
<span class="prism--token prism--comment">// read and return PsiFile</span>
<span class="prism--token prism--punctuation">}</span></code></pre><div class="copy-button__container"><div class="copy-button" data-clipboard-target="#code-80ByD7lSAg_SJ3Ads3Aqv" data-test="copy-button" role="button" tabindex="0"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_l copy-button__icon"><path d="M9 5h10v10H9z"></path><path d="M7 9H5v10h10v-2H7V9z"></path></svg></div></div></div></div><p id="z7olnq5_155" class="article__p child">Note that this API is obsolete since 2024.1. Plugins implemented in Kotlin and targeting versions 2024.1+ should use suspending <a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/core-api/src/com/intellij/openapi/application/coroutines.kt" data-test="external-link " rel="" class="link link--external" id="z7olnq5_158"><code class="code" id="z7olnq5_160">readAction()</code></a>. See also <a data-test="internal-link link-with-popover" rel="" class="link" id="z7olnq5_159" href="coroutine-read-actions.html">Coroutine Read Actions</a>.</p></li></ul></div></div></section></section><section class="chapter h3-related"><h4 id="read-actions-rules" data-toc="read-actions-rules" class="article__h4"><span class="title"><span class="title__content">Rules</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#read-actions-rules"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#read-actions-rules"><svg viewBox="0 0 16 16" class="wt-icon wt-icon_size_xs permalink__icon permalink__icon--size-xs"><path d="M14.094 3.801a3.093 3.093 0 0 0-4.373 0L6.653 6.87l.964.964 3.068-3.069A1.729 1.729 0 0 1 13.13 7.21l-3.068 3.069.964.964 3.068-3.068a3.093 3.093 0 0 0 0-4.374z"></path><path d="M5.313 11.618a1.729 1.729 0 0 1-2.445-2.445l3.068-3.068-.964-.964-3.068 3.068a3.092 3.092 0 0 0 4.373 4.374l3.069-3.069-.965-.964z"></path></svg></span></a></span></h4><div data-test="tab-list-wrapper"><div class="_wrapper_edyv3p_4 _light_edyv3p_82"><div class="_arrow_edyv3p_39 _arrowLeft_edyv3p_99" data-test="scrollable-list-arrow-left-wrapper" style="height: 100%;"><div data-test="scrollable-list-arrow-left" class="_main_g361av_17 _modeClear_g361av_434 _sizeS_g361av_92 _alignIconLeft_g361av_77 _light_g361av_59 _withIcon_g361av_119 _withoutText_g361av_113"><svg viewBox="0 0 24 24" class="_icon_1r3x2p9_3 _sizeM_1r3x2p9_12 _icon_g361av_529"><path d="M15.004 19V5l-8 7 8 7z"></path></svg></div><div class="_arrowShadow_edyv3p_39"></div></div><div class="_scrollable_edyv3p_10"><div class="_tabsContainer_1fcqo6x_13 _light_1fcqo6x_31 _classic_1fcqo6x_31 _sizeM_1fcqo6x_99 _innerOffsetM_1fcqo6x_109 tabs h4-related undefined" data-test="tab-list"><div class="_tab_1fcqo6x_13 _selected_1fcqo6x_141 _short_1fcqo6x_133" role="tab" tabindex="0" data-e2e="tab" data-test="tab tab-selected"><div><div data-test="tab-title" id="z7olnq5_164">2023.3+</div></div></div><div class="_tab_1fcqo6x_13 _short_1fcqo6x_133" role="tab" tabindex="0" data-e2e="tab" data-test="tab"><div><div data-test="tab-title" id="z7olnq5_165">Earlier versions</div></div></div><span class="_indicator_1fcqo6x_19" style="left: 0px; width: 61.1719px;"></span></div></div><div class="_arrow_edyv3p_39 _arrowRight_edyv3p_112" data-test="scrollable-list-arrow-right-wrapper" style="height: 100%;"><div data-test="scrollable-list-arrow-right" class="_main_g361av_17 _modeClear_g361av_434 _sizeS_g361av_92 _alignIconLeft_g361av_77 _light_g361av_59 _withIcon_g361av_119 _withoutText_g361av_113 _arrowButton_edyv3p_126"><svg viewBox="0 0 24 24" class="_icon_1r3x2p9_3 _sizeM_1r3x2p9_12 _icon_g361av_529"><path d="M9.004 19l8-7-8-7v14z"></path></svg></div><div class="_arrowShadow_edyv3p_39"></div></div></div><div data-test="tab-content" class="tabs__content-wrapper"><div class="tabs__content" data-gtm="tab" data-sync-tabs="newThreading" data-title="2023.3+" data-tab-id="z7olnq5_164"><p id="z7olnq5_166" class="article__p child">Reading data is allowed from any thread.</p><p id="z7olnq5_167" class="article__p child">Reading data on EDT invoked with <code class="code" id="z7olnq5_168">Application.invokeLater()</code> doesn't require an explicit read action, as the write intent lock allowing to read data is <a data-test="internal-link " rel="" class="link" id="z7olnq5_169" href="/docs/intellij/threading-model.html#locks-and-edt">acquired implicitly</a>.</p></div></div><div data-test="tab-content" class="tabs__content-wrapper" style="display: none;"><div class="tabs__content" data-gtm="tab" data-sync-tabs="oldThreading" data-title="Earlier versions" data-tab-id="z7olnq5_165"><p id="z7olnq5_170" class="article__p child">Reading data is allowed from any thread.</p><p id="z7olnq5_171" class="article__p child">Reading data on EDT doesn't require an explicit read action, as the write intent lock allowing to read data is <a data-test="internal-link " rel="" class="link" id="z7olnq5_172" href="/docs/intellij/threading-model.html#locks-and-edt">acquired implicitly</a>.</p></div></div></div><p id="z7olnq5_162" class="article__p h4-related">In all other cases, it is required to wrap read operation in a read action with one of the <a data-test="internal-link " rel="" class="link" id="z7olnq5_173" href="/docs/intellij/threading-model.html#read-actions-api">API</a> methods.</p><section class="chapter h4-related"><h5 id="objects-validity" data-toc="objects-validity" class="article__h5"><span class="title"><span class="title__content">Objects Validity</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#objects-validity"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#objects-validity"><svg viewBox="0 0 16 16" class="wt-icon wt-icon_size_xs permalink__icon permalink__icon--size-xs"><path d="M14.094 3.801a3.093 3.093 0 0 0-4.373 0L6.653 6.87l.964.964 3.068-3.069A1.729 1.729 0 0 1 13.13 7.21l-3.068 3.069.964.964 3.068-3.068a3.093 3.093 0 0 0 0-4.374z"></path><path d="M5.313 11.618a1.729 1.729 0 0 1-2.445-2.445l3.068-3.068-.964-.964-3.068 3.068a3.092 3.092 0 0 0 4.373 4.374l3.069-3.069-.965-.964z"></path></svg></span></a></span></h5><p id="z7olnq5_174" class="article__p h5-related">The read objects aren't guaranteed to survive between several consecutive read actions. Whenever starting a read action, check if the PSI/VFS/project/module is still valid. Example:</p><div class="code-block__wrapper"><div id="" class="code-block h5-related in-flow" data-test="code-block"><pre class="code-block__pre language-kotlin" id="code-X9hHdnOruDhxeoNFu02Bo"><code><span class="prism--token prism--keyword">val</span> virtualFile <span class="prism--token prism--operator">=</span> runReadAction <span class="prism--token prism--punctuation">{</span> <span class="prism--token prism--comment">// read action 1</span>
<span class="prism--token prism--comment">// read a virtual file</span>
<span class="prism--token prism--punctuation">}</span>
<span class="prism--token prism--comment">// do other time-consuming work...</span>
<span class="prism--token prism--keyword">val</span> psiFile <span class="prism--token prism--operator">=</span> runReadAction <span class="prism--token prism--punctuation">{</span> <span class="prism--token prism--comment">// read action 2</span>
<span class="prism--token prism--keyword">if</span> <span class="prism--token prism--punctuation">(</span>virtualFile<span class="prism--token prism--punctuation">.</span><span class="prism--token prism--function">isValid</span><span class="prism--token prism--punctuation">(</span><span class="prism--token prism--punctuation">)</span><span class="prism--token prism--punctuation">)</span> <span class="prism--token prism--punctuation">{</span> <span class="prism--token prism--comment">// check if the virtual file is valid</span>
PsiManager<span class="prism--token prism--punctuation">.</span><span class="prism--token prism--function">getInstance</span><span class="prism--token prism--punctuation">(</span>project<span class="prism--token prism--punctuation">)</span><span class="prism--token prism--punctuation">.</span><span class="prism--token prism--function">findFile</span><span class="prism--token prism--punctuation">(</span>virtualFile<span class="prism--token prism--punctuation">)</span>
<span class="prism--token prism--punctuation">}</span> <span class="prism--token prism--keyword">else</span> <span class="prism--token prism--keyword">null</span>
<span class="prism--token prism--punctuation">}</span></code></pre><div class="copy-button__container"><div class="copy-button" data-clipboard-target="#code-X9hHdnOruDhxeoNFu02Bo" data-test="copy-button" role="button" tabindex="0"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_l copy-button__icon"><path d="M9 5h10v10H9z"></path><path d="M7 9H5v10h10v-2H7V9z"></path></svg></div></div></div></div><p id="z7olnq5_176" class="article__p h5-related">Between executing first and second read actions, another thread could invalidate the virtual file:</p><svg aria-roledescription="gantt" role="graphics-document document" viewBox="0 0 800 148" xmlns="http://www.w3.org/2000/svg" width="100%" id="mermaid" class="h5-related" style="max-width: 800px;"><g></g><g text-anchor="middle" font-family="sans-serif" font-size="10" fill="none" transform="translate(75, 98)" class="grid"><path d="M0.5,-63V0.5H650.5V-63" stroke="currentColor" class="domain"></path><g transform="translate(0.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(65.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(130.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(195.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(260.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(325.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(390.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(455.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(520.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(585.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(650.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g></g><g><rect class="section section0" height="24" width="762.5" y="48" x="0"></rect><rect class="section section1" height="24" width="762.5" y="72" x="0"></rect></g><g><rect class="task task0" transform-origin="140px 60px" height="20" width="130" y="50" x="75" ry="3" rx="3" id="task1"></rect><rect class="task done0" transform-origin="400px 60px" height="20" width="390" y="50" x="205" ry="3" rx="3" id="task2"></rect><rect class="task crit1" transform-origin="400px 84px" height="20" width="130" y="74" x="335" ry="3" rx="3" id="task4"></rect><rect class="task task0" transform-origin="660px 60px" height="20" width="130" y="50" x="595" ry="3" rx="3" id="task3"></rect><text class="taskText taskText0 width-63.921875" y="63.5" x="140" font-size="11" id="task1-text">read action 1 </text><text class="taskText taskText0 doneText0 width-104.8519287109375" y="63.5" x="400" font-size="11" id="task2-text">time-consuming work </text><text class="taskText taskText1 critText1 width-79.953125" y="87.5" x="400" font-size="11" id="task4-text">delete virtual file </text><text class="taskText taskText0 width-63.921875" y="63.5" x="660" font-size="11" id="task3-text">read action 2 </text></g><g><text class="sectionTitle sectionTitle0" font-size="11" y="62" x="10" dy="0em"><tspan x="10" alignment-baseline="central">Thread 1</tspan></text><text class="sectionTitle sectionTitle1" font-size="11" y="86" x="10" dy="0em"><tspan x="10" alignment-baseline="central">Thread 2</tspan></text></g><g class="today"><line class="today" y2="123" y1="25" x2="225397127528" x1="225397127528"></line></g><text class="titleText" y="25" x="400"></text></svg></section></section></section><section class="chapter h2-related"><h3 id="write-actions" data-toc="write-actions" class="article__h3"><span class="title"><span class="title__content">Write Actions</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#write-actions"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#write-actions"><svg viewBox="0 0 16 16" class="wt-icon wt-icon_size_xs permalink__icon permalink__icon--size-xs"><path d="M14.094 3.801a3.093 3.093 0 0 0-4.373 0L6.653 6.87l.964.964 3.068-3.069A1.729 1.729 0 0 1 13.13 7.21l-3.068 3.069.964.964 3.068-3.068a3.093 3.093 0 0 0 0-4.374z"></path><path d="M5.313 11.618a1.729 1.729 0 0 1-2.445-2.445l3.068-3.068-.964-.964-3.068 3.068a3.092 3.092 0 0 0 4.373 4.374l3.069-3.069-.965-.964z"></path></svg></span></a></span></h3><section class="chapter h3-related"><h4 id="write-actions-api" data-toc="write-actions-api" class="article__h4"><span class="title"><span class="title__content">API</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#write-actions-api"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#write-actions-api"><svg viewBox="0 0 16 16" class="wt-icon wt-icon_size_xs permalink__icon permalink__icon--size-xs"><path d="M14.094 3.801a3.093 3.093 0 0 0-4.373 0L6.653 6.87l.964.964 3.068-3.069A1.729 1.729 0 0 1 13.13 7.21l-3.068 3.069.964.964 3.068-3.068a3.093 3.093 0 0 0 0-4.374z"></path><path d="M5.313 11.618a1.729 1.729 0 0 1-2.445-2.445l3.068-3.068-.964-.964-3.068 3.068a3.092 3.092 0 0 0 4.373 4.374l3.069-3.069-.965-.964z"></path></svg></span></a></span></h4><ul class="article__list list _bullet h4-related" id="z7olnq5_180"><li class="list__item" id="z7olnq5_182"><p id="z7olnq5_183" class="article__p child"><a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/core-api/src/com/intellij/openapi/application/WriteAction.java" data-test="external-link " rel="" class="link link--external" id="z7olnq5_185"><code class="code" id="z7olnq5_188">WriteAction</code></a> <code class="code" id="z7olnq5_186">run()</code> or <code class="code" id="z7olnq5_187">compute()</code>:</p><div data-test="tab-list-wrapper"><div class="_wrapper_edyv3p_4 _light_edyv3p_82"><div class="_arrow_edyv3p_39 _arrowLeft_edyv3p_99" data-test="scrollable-list-arrow-left-wrapper" style="height: 100%;"><div data-test="scrollable-list-arrow-left" class="_main_g361av_17 _modeClear_g361av_434 _sizeS_g361av_92 _alignIconLeft_g361av_77 _light_g361av_59 _withIcon_g361av_119 _withoutText_g361av_113"><svg viewBox="0 0 24 24" class="_icon_1r3x2p9_3 _sizeM_1r3x2p9_12 _icon_g361av_529"><path d="M15.004 19V5l-8 7 8 7z"></path></svg></div><div class="_arrowShadow_edyv3p_39"></div></div><div class="_scrollable_edyv3p_10"><div class="_tabsContainer_1fcqo6x_13 _light_1fcqo6x_31 _classic_1fcqo6x_31 _sizeM_1fcqo6x_99 _innerOffsetM_1fcqo6x_109 tabs tabs--nested child undefined" data-test="tab-list"><div class="_tab_1fcqo6x_13 _selected_1fcqo6x_141 _short_1fcqo6x_133" role="tab" tabindex="0" data-e2e="tab" data-test="tab tab-selected"><div><div data-test="tab-title" id="z7olnq5_189">Kotlin</div></div></div><div class="_tab_1fcqo6x_13 _short_1fcqo6x_133" role="tab" tabindex="0" data-e2e="tab" data-test="tab"><div><div data-test="tab-title" id="z7olnq5_190">Java</div></div></div><span class="_indicator_1fcqo6x_19" style="left: 0px; width: 43.1562px;"></span></div></div><div class="_arrow_edyv3p_39 _arrowRight_edyv3p_112" data-test="scrollable-list-arrow-right-wrapper" style="height: 100%;"><div data-test="scrollable-list-arrow-right" class="_main_g361av_17 _modeClear_g361av_434 _sizeS_g361av_92 _alignIconLeft_g361av_77 _light_g361av_59 _withIcon_g361av_119 _withoutText_g361av_113 _arrowButton_edyv3p_126"><svg viewBox="0 0 24 24" class="_icon_1r3x2p9_3 _sizeM_1r3x2p9_12 _icon_g361av_529"><path d="M9.004 19l8-7-8-7v14z"></path></svg></div><div class="_arrowShadow_edyv3p_39"></div></div></div><div data-test="tab-content" class="tabs__content-wrapper tabs__content-wrapper--nested"><div class="tabs__content" data-gtm="tab" data-sync-tabs="kotlin" data-title="Kotlin" data-tab-id="z7olnq5_189"><div class="code-block__wrapper"><div id="" class="code-block code-block child" data-test="code-block"><pre class="code-block__pre language-kotlin" id="code-ri8J0BlDslxKE_P7zys6_"><code>WriteAction<span class="prism--token prism--punctuation">.</span>run<span class="prism--token prism--operator"><</span>Throwable<span class="prism--token prism--operator">></span> <span class="prism--token prism--punctuation">{</span>
<span class="prism--token prism--comment">// write data</span>
<span class="prism--token prism--punctuation">}</span></code></pre><div class="copy-button__container"><div class="copy-button" data-clipboard-target="#code-ri8J0BlDslxKE_P7zys6_" data-test="copy-button" role="button" tabindex="0"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_l copy-button__icon"><path d="M9 5h10v10H9z"></path><path d="M7 9H5v10h10v-2H7V9z"></path></svg></div></div></div></div></div></div><div data-test="tab-content" class="tabs__content-wrapper tabs__content-wrapper--nested" style="display: none;"><div class="tabs__content" data-gtm="tab" data-sync-tabs="java" data-title="Java" data-tab-id="z7olnq5_190"><div class="code-block__wrapper"><div id="" class="code-block code-block child" data-test="code-block"><pre class="code-block__pre language-java" id="code-9EZTXwVrCI9uDih0DDviE"><code><span class="prism--token prism--class-name">WriteAction</span><span class="prism--token prism--punctuation">.</span><span class="prism--token prism--function">run</span><span class="prism--token prism--punctuation">(</span><span class="prism--token prism--punctuation">(</span><span class="prism--token prism--punctuation">)</span> <span class="prism--token prism--operator">-></span> <span class="prism--token prism--punctuation">{</span>
<span class="prism--token prism--comment">// write data</span>
<span class="prism--token prism--punctuation">}</span><span class="prism--token prism--punctuation">)</span><span class="prism--token prism--punctuation">;</span></code></pre><div class="copy-button__container"><div class="copy-button" data-clipboard-target="#code-9EZTXwVrCI9uDih0DDviE" data-test="copy-button" role="button" tabindex="0"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_l copy-button__icon"><path d="M9 5h10v10H9z"></path><path d="M7 9H5v10h10v-2H7V9z"></path></svg></div></div></div></div></div></div></div></li></ul><section class="chapter h4-related"><div class="collapse" data-test="collapse-element" data-is-animating="false" data-test-is-animating="false"><div class="collapse__header collapse__title" role="button" tabindex="0" aria-expanded="false" data-test="collapse-header"><h5 id="write-action-alternative-apis" data-toc="write-action-alternative-apis" class="article__h5"><span class="title"><span class="title__content">Alternative APIs</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#write-action-alternative-apis"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#write-action-alternative-apis"><svg viewBox="0 0 16 16" class="wt-icon wt-icon_size_xs permalink__icon permalink__icon--size-xs"><path d="M14.094 3.801a3.093 3.093 0 0 0-4.373 0L6.653 6.87l.964.964 3.068-3.069A1.729 1.729 0 0 1 13.13 7.21l-3.068 3.069.964.964 3.068-3.068a3.093 3.093 0 0 0 0-4.374z"></path><path d="M5.313 11.618a1.729 1.729 0 0 1-2.445-2.445l3.068-3.068-.964-.964-3.068 3.068a3.092 3.092 0 0 0 4.373 4.374l3.069-3.069-.965-.964z"></path></svg></span></a></span></h5><div class="collapse__button" data-test="collapse-button" aria-hidden="true" style="top: -2px;"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_m collapse__icon"><path d="M21 12a9 9 0 1 1-9-9 9 9 0 0 1 9 9zm-4.235-3.351l-1.414-1.414L12 10.585 8.635 7.222 7.221 8.635 10.586 12l-3.257 3.257 1.414 1.414L12 13.414l3.288 3.289 1.415-1.415L13.414 12z"></path></svg></div></div><div class="collapse__body" data-test="collapse-content" aria-hidden="true"><ul class="article__list list _bullet child list--nested" id="z7olnq5_193"><li class="list__item" id="z7olnq5_194"><p id="z7olnq5_196" class="article__p child"><a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/core-api/src/com/intellij/openapi/application/Application.java" data-test="external-link " rel="" class="link link--external" id="z7olnq5_198"><code class="code" id="z7olnq5_199">Application.runWriteAction()</code></a>:</p><div data-test="tab-list-wrapper"><div class="_wrapper_edyv3p_4 _light_edyv3p_82"><div class="_arrow_edyv3p_39 _arrowLeft_edyv3p_99" data-test="scrollable-list-arrow-left-wrapper" style="height: 100%;"><div data-test="scrollable-list-arrow-left" class="_main_g361av_17 _modeClear_g361av_434 _sizeS_g361av_92 _alignIconLeft_g361av_77 _light_g361av_59 _withIcon_g361av_119 _withoutText_g361av_113"><svg viewBox="0 0 24 24" class="_icon_1r3x2p9_3 _sizeM_1r3x2p9_12 _icon_g361av_529"><path d="M15.004 19V5l-8 7 8 7z"></path></svg></div><div class="_arrowShadow_edyv3p_39"></div></div><div class="_scrollable_edyv3p_10"><div class="_tabsContainer_1fcqo6x_13 _light_1fcqo6x_31 _classic_1fcqo6x_31 _sizeM_1fcqo6x_99 _innerOffsetM_1fcqo6x_109 tabs tabs--nested child undefined" data-test="tab-list"><div class="_tab_1fcqo6x_13 _selected_1fcqo6x_141 _short_1fcqo6x_133" role="tab" tabindex="0" data-e2e="tab" data-test="tab tab-selected"><div><div data-test="tab-title" id="z7olnq5_200">Kotlin</div></div></div><div class="_tab_1fcqo6x_13 _short_1fcqo6x_133" role="tab" tabindex="0" data-e2e="tab" data-test="tab"><div><div data-test="tab-title" id="z7olnq5_201">Java</div></div></div><span class="_indicator_1fcqo6x_19" style="left: 0px; width: 43.1562px;"></span></div></div><div class="_arrow_edyv3p_39 _arrowRight_edyv3p_112" data-test="scrollable-list-arrow-right-wrapper" style="height: 100%;"><div data-test="scrollable-list-arrow-right" class="_main_g361av_17 _modeClear_g361av_434 _sizeS_g361av_92 _alignIconLeft_g361av_77 _light_g361av_59 _withIcon_g361av_119 _withoutText_g361av_113 _arrowButton_edyv3p_126"><svg viewBox="0 0 24 24" class="_icon_1r3x2p9_3 _sizeM_1r3x2p9_12 _icon_g361av_529"><path d="M9.004 19l8-7-8-7v14z"></path></svg></div><div class="_arrowShadow_edyv3p_39"></div></div></div><div data-test="tab-content" class="tabs__content-wrapper tabs__content-wrapper--nested"><div class="tabs__content" data-gtm="tab" data-sync-tabs="kotlin" data-title="Kotlin" data-tab-id="z7olnq5_200"><div class="code-block__wrapper"><div id="" class="code-block code-block child" data-test="code-block"><pre class="code-block__pre language-kotlin" id="code-fIWonavjF2UiY_Z7gGrxj"><code>ApplicationManager<span class="prism--token prism--punctuation">.</span>application<span class="prism--token prism--punctuation">.</span><span class="prism--token prism--function">runWriteAction</span> <span class="prism--token prism--punctuation">{</span>
<span class="prism--token prism--comment">// write data</span>
<span class="prism--token prism--punctuation">}</span></code></pre><div class="copy-button__container"><div class="copy-button" data-clipboard-target="#code-fIWonavjF2UiY_Z7gGrxj" data-test="copy-button" role="button" tabindex="0"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_l copy-button__icon"><path d="M9 5h10v10H9z"></path><path d="M7 9H5v10h10v-2H7V9z"></path></svg></div></div></div></div></div></div><div data-test="tab-content" class="tabs__content-wrapper tabs__content-wrapper--nested" style="display: none;"><div class="tabs__content" data-gtm="tab" data-sync-tabs="java" data-title="Java" data-tab-id="z7olnq5_201"><div class="code-block__wrapper"><div id="" class="code-block code-block child" data-test="code-block"><pre class="code-block__pre language-java" id="code-Sc1qFqitaMZHgIjbCOr_V"><code><span class="prism--token prism--class-name">ApplicationManager</span><span class="prism--token prism--punctuation">.</span><span class="prism--token prism--function">getApplication</span><span class="prism--token prism--punctuation">(</span><span class="prism--token prism--punctuation">)</span><span class="prism--token prism--punctuation">.</span><span class="prism--token prism--function">runWriteAction</span><span class="prism--token prism--punctuation">(</span><span class="prism--token prism--punctuation">(</span><span class="prism--token prism--punctuation">)</span> <span class="prism--token prism--operator">-></span> <span class="prism--token prism--punctuation">{</span>
<span class="prism--token prism--comment">// write data</span>
<span class="prism--token prism--punctuation">}</span><span class="prism--token prism--punctuation">)</span><span class="prism--token prism--punctuation">;</span></code></pre><div class="copy-button__container"><div class="copy-button" data-clipboard-target="#code-Sc1qFqitaMZHgIjbCOr_V" data-test="copy-button" role="button" tabindex="0"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_l copy-button__icon"><path d="M9 5h10v10H9z"></path><path d="M7 9H5v10h10v-2H7V9z"></path></svg></div></div></div></div></div></div></div><p class="article__p child"> Note that this API is considered low-level and should be avoided.</p></li><li class="list__item" id="z7olnq5_195"><p id="z7olnq5_204" class="article__p child">Kotlin <a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/core-api/src/com/intellij/openapi/application/actions.kt" data-test="external-link " rel="" class="link link--external" id="z7olnq5_207"><code class="code" id="z7olnq5_208">runWriteAction()</code></a>:</p><div class="code-block__wrapper"><div id="" class="code-block child in-flow" data-test="code-block"><pre class="code-block__pre language-kotlin" id="code-b5ftCHpVRKuzUrRp0SwoY"><code>runWriteAction <span class="prism--token prism--punctuation">{</span>
<span class="prism--token prism--comment">// write data</span>
<span class="prism--token prism--punctuation">}</span></code></pre><div class="copy-button__container"><div class="copy-button" data-clipboard-target="#code-b5ftCHpVRKuzUrRp0SwoY" data-test="copy-button" role="button" tabindex="0"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_l copy-button__icon"><path d="M9 5h10v10H9z"></path><path d="M7 9H5v10h10v-2H7V9z"></path></svg></div></div></div></div><p id="z7olnq5_206" class="article__p child">Note that this API is obsolete since 2024.1. Plugins implemented in Kotlin and targeting versions 2024.1+ should use suspending <a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/core-api/src/com/intellij/openapi/application/coroutines.kt" data-test="external-link " rel="" class="link link--external" id="z7olnq5_209"><code class="code" id="z7olnq5_210">writeAction()</code></a>.</p></li></ul></div></div></section></section><section class="chapter h3-related"><h4 id="write-actions-rules" data-toc="write-actions-rules" class="article__h4"><span class="title"><span class="title__content">Rules</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#write-actions-rules"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#write-actions-rules"><svg viewBox="0 0 16 16" class="wt-icon wt-icon_size_xs permalink__icon permalink__icon--size-xs"><path d="M14.094 3.801a3.093 3.093 0 0 0-4.373 0L6.653 6.87l.964.964 3.068-3.069A1.729 1.729 0 0 1 13.13 7.21l-3.068 3.069.964.964 3.068-3.068a3.093 3.093 0 0 0 0-4.374z"></path><path d="M5.313 11.618a1.729 1.729 0 0 1-2.445-2.445l3.068-3.068-.964-.964-3.068 3.068a3.092 3.092 0 0 0 4.373 4.374l3.069-3.069-.965-.964z"></path></svg></span></a></span></h4><div data-test="tab-list-wrapper"><div class="_wrapper_edyv3p_4 _light_edyv3p_82"><div class="_arrow_edyv3p_39 _arrowLeft_edyv3p_99" data-test="scrollable-list-arrow-left-wrapper" style="height: 100%;"><div data-test="scrollable-list-arrow-left" class="_main_g361av_17 _modeClear_g361av_434 _sizeS_g361av_92 _alignIconLeft_g361av_77 _light_g361av_59 _withIcon_g361av_119 _withoutText_g361av_113"><svg viewBox="0 0 24 24" class="_icon_1r3x2p9_3 _sizeM_1r3x2p9_12 _icon_g361av_529"><path d="M15.004 19V5l-8 7 8 7z"></path></svg></div><div class="_arrowShadow_edyv3p_39"></div></div><div class="_scrollable_edyv3p_10"><div class="_tabsContainer_1fcqo6x_13 _light_1fcqo6x_31 _classic_1fcqo6x_31 _sizeM_1fcqo6x_99 _innerOffsetM_1fcqo6x_109 tabs h4-related undefined" data-test="tab-list"><div class="_tab_1fcqo6x_13 _selected_1fcqo6x_141 _short_1fcqo6x_133" role="tab" tabindex="0" data-e2e="tab" data-test="tab tab-selected"><div><div data-test="tab-title" id="z7olnq5_213">2023.3+</div></div></div><div class="_tab_1fcqo6x_13 _short_1fcqo6x_133" role="tab" tabindex="0" data-e2e="tab" data-test="tab"><div><div data-test="tab-title" id="z7olnq5_214">Earlier versions</div></div></div><span class="_indicator_1fcqo6x_19" style="left: 0px; width: 61.1719px;"></span></div></div><div class="_arrow_edyv3p_39 _arrowRight_edyv3p_112" data-test="scrollable-list-arrow-right-wrapper" style="height: 100%;"><div data-test="scrollable-list-arrow-right" class="_main_g361av_17 _modeClear_g361av_434 _sizeS_g361av_92 _alignIconLeft_g361av_77 _light_g361av_59 _withIcon_g361av_119 _withoutText_g361av_113 _arrowButton_edyv3p_126"><svg viewBox="0 0 24 24" class="_icon_1r3x2p9_3 _sizeM_1r3x2p9_12 _icon_g361av_529"><path d="M9.004 19l8-7-8-7v14z"></path></svg></div><div class="_arrowShadow_edyv3p_39"></div></div></div><div data-test="tab-content" class="tabs__content-wrapper"><div class="tabs__content" data-gtm="tab" data-sync-tabs="newThreading" data-title="2023.3+" data-tab-id="z7olnq5_213"><p id="z7olnq5_215" class="article__p child">Writing data is only allowed on EDT invoked with <code class="code" id="z7olnq5_218">Application.invokeLater()</code>.</p><p id="z7olnq5_216" class="article__p child">Write operations must always be wrapped in a write action with one of the <a data-test="internal-link " rel="" class="link" id="z7olnq5_219" href="/docs/intellij/threading-model.html#write-actions-api">API</a> methods.</p><p id="z7olnq5_217" class="article__p child">Modifying the model is only allowed from write-safe contexts (see <a data-test="internal-link " rel="" class="link" id="z7olnq5_220" href="/docs/intellij/threading-model.html#invoking-operations-on-edt-and-modality">Invoking Operations on EDT and Modality</a>).</p></div></div><div data-test="tab-content" class="tabs__content-wrapper" style="display: none;"><div class="tabs__content" data-gtm="tab" data-sync-tabs="oldThreading" data-title="Earlier versions" data-tab-id="z7olnq5_214"><p id="z7olnq5_221" class="article__p child">Writing data is only allowed on EDT.</p><p id="z7olnq5_222" class="article__p child">Write operations must always be wrapped in a write action with one of the <a data-test="internal-link " rel="" class="link" id="z7olnq5_225" href="/docs/intellij/threading-model.html#write-actions-api">API</a> methods.</p><p id="z7olnq5_223" class="article__p child">Modifying the model is only allowed from write-safe contexts, including user actions and <code class="code" id="z7olnq5_226">SwingUtilities.invokeLater()</code> calls from them (see <a data-test="internal-link " rel="" class="link" id="z7olnq5_227" href="/docs/intellij/threading-model.html#invoking-operations-on-edt-and-modality">Invoking Operations on EDT and Modality</a>).</p><p id="z7olnq5_224" class="article__p child">Modifying PSI, VFS, or project model from inside UI renderers or <code class="code" id="z7olnq5_228">SwingUtilities.invokeLater()</code> calls is forbidden.</p></div></div></div><blockquote class="prompt h4-related" data-test-id="J472kG9ovbKiD1G1TpuT_"><h3 class="a11y-title">tip</h3><div class="prompt__wrapper prompt__wrapper--type-tip" data-test="prompt"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_m prompt__icon"><circle cx="12.042" cy="4" r="2"></circle><path d="M18.339 7a6.982 6.982 0 0 0-6.3 4 6.982 6.982 0 0 0-6.3-4H3v10h2.739a6.983 6.983 0 0 1 6.3 4 6.582 6.582 0 0 1 6-4.033h2.994L21 7z"></path></svg><div class="prompt__content"><p id="z7olnq5_229" class="article__p child"><a href="https://plugins.jetbrains.com/plugin/16815-thread-access-info" data-test="external-link " rel="" class="link link--external" id="z7olnq5_230">Thread Access Info</a> plugin visualizes Read/Write Access and Thread information in the debugger.</p></div></div></blockquote></section></section></section><section class="chapter h1-related"><h2 id="invoking-operations-on-edt-and-modality" data-toc="invoking-operations-on-edt-and-modality" class="article__h2"><span class="title"><span class="title__content">Invoking Operations on EDT and Modality</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#invoking-operations-on-edt-and-modality"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#invoking-operations-on-edt-and-modality"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_s permalink__icon permalink__icon--size-s"><path d="M21.207 4.793a4.536 4.536 0 0 0-6.414 0l-4.5 4.5 1.414 1.414 4.5-4.5a2.536 2.536 0 0 1 3.586 3.586l-4.5 4.5 1.414 1.414 4.5-4.5a4.536 4.536 0 0 0 0-6.414z"></path><path d="M8.328 16.258a2.536 2.536 0 1 1-3.586-3.586l4.5-4.5-1.414-1.414-4.5 4.5a4.535 4.535 0 0 0 6.414 6.414l4.5-4.5-1.414-1.414z"></path></svg></span></a></span></h2><p id="z7olnq5_231" class="article__p h2-related">Operations that write data on EDT should be invoked with <code class="code" id="z7olnq5_243">Application.invokeLater()</code> because it allows specifying the <span class="emphasis" id="z7olnq5_244">modality state</span> (<a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/core-api/src/com/intellij/openapi/application/ModalityState.java" data-test="external-link " rel="" class="link link--external" id="z7olnq5_245"><code class="code" id="z7olnq5_247">ModalityState</code></a>) for the scheduled operation. This is not supported by <code class="code" id="z7olnq5_246">SwingUtilities.invokeLater()</code> and similar APIs.</p><blockquote class="prompt h2-related" data-test-id="0iY6svG7R5SHJH8Vs_k5Y"><h3 class="a11y-title">warning</h3><div class="prompt__wrapper prompt__wrapper--type-warning" data-test="prompt"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_m prompt__icon"><path d="M12.946 3.552L21.52 18.4c.424.735.33 1.6-.519 1.6H3.855c-.85 0-1.817-.865-1.392-1.6l8.573-14.848a1.103 1.103 0 0 1 1.91 0zm.545 12.948a1.5 1.5 0 1 0-1.5 1.5 1.5 1.5 0 0 0 1.5-1.5zM13 8h-2v5h2z"></path></svg><div class="prompt__content"><p id="z7olnq5_248" class="article__p child">Note that <code class="code" id="z7olnq5_249">Application.invokeLater()</code> must be used to write data in versions 2023.3+.</p></div></div></blockquote><p id="z7olnq5_233" class="article__p h2-related"><code class="code" id="z7olnq5_250">ModalityState</code> represents the stack of active modal dialogs and is used in calls to <code class="code" id="z7olnq5_251">Application.invokeLater()</code> to ensure the scheduled runnable can execute within the given modality state, meaning when the same set of modal dialogs or a subset is present.</p><p id="z7olnq5_234" class="article__p h2-related">To better understand what problem <code class="code" id="z7olnq5_252">ModalityState</code> solves, consider the following scenario:</p><ol class="article__list list _decimal h2-related" id="z7olnq5_235" type="1"><li class="list__item" id="z7olnq5_253"><p class="article__p child">A user action is started.</p></li><li class="list__item" id="z7olnq5_254"><p class="article__p child">In the meantime, another operation is scheduled on EDT with <code class="code" id="z7olnq5_259">SwingUtilities.invokeLater()</code> (without modality state support).</p></li><li class="list__item" id="z7olnq5_255"><p class="article__p child">The action from 1. now shows a dialog asking a <span class="control" id="z7olnq5_260">Yes</span>/<span class="control" id="z7olnq5_261">No</span> question.</p></li><li class="list__item" id="z7olnq5_256"><p class="article__p child">While the dialog is shown, the operation from 2. is now processed and does changes to the data model, which invalidates PSI.</p></li><li class="list__item" id="z7olnq5_257"><p class="article__p child">The user clicks <span class="control" id="z7olnq5_262">Yes</span> or <span class="control" id="z7olnq5_263">No</span> in the dialog, and it executes some code based on the answer.</p></li><li class="list__item" id="z7olnq5_258"><p class="article__p child">Now, the code to be executed as the result of the user's answer has to deal with the changed data model it was not prepared for. For example, it was supposed to execute changes in the PSI that might be already invalid.</p></li></ol><svg aria-roledescription="gantt" role="graphics-document document" viewBox="0 0 800 148" xmlns="http://www.w3.org/2000/svg" width="100%" id="mermaid" class="h2-related" style="max-width: 800px;"><g></g><g text-anchor="middle" font-family="sans-serif" font-size="10" fill="none" transform="translate(75, 98)" class="grid"><path d="M0.5,-63V0.5H650.5V-63" stroke="currentColor" class="domain"></path><g transform="translate(0.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(46.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(93.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(139.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(186.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(232.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(279.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(325.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(371.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(418.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(464.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(511.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(557.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(604.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(650.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g></g><g><rect class="section section0" height="24" width="762.5" y="48" x="0"></rect><rect class="section section1" height="24" width="762.5" y="72" x="0"></rect></g><g><rect class="task task0" transform-origin="168px 60px" height="20" width="186" y="50" x="75" ry="3" rx="3" id="task1"></rect><rect class="task activeCrit1" transform-origin="214.5px 84px" height="20" width="93" y="74" x="168" ry="3" rx="3" id="task6"></rect><rect class="task task0" transform-origin="307.5px 60px" height="20" width="93" y="50" x="261" ry="3" rx="3" id="task2"></rect><rect class="task activeCrit0" transform-origin="400px 60px" height="20" width="92" y="50" x="354" ry="3" rx="3" id="task3"></rect><rect class="task task0" transform-origin="492.5px 60px" height="20" width="93" y="50" x="446" ry="3" rx="3" id="task4"></rect><rect class="task crit0" transform-origin="632px 60px" height="20" width="186" y="50" x="539" ry="3" rx="3" id="task5"></rect><text class="taskText taskText0 width-68.234375" y="63.5" x="168" font-size="11" id="task1-text">1. Start action </text><text class="taskText taskText1 activeCritText1 critText1 width-76.8125" y="87.5" x="214.5" font-size="11" id="task6-text">2. invokeLater() </text><text class="taskText taskText0 width-72.5" y="63.5" x="307.5" font-size="11" id="task2-text">3. Show dialog </text><text class="taskText taskText0 activeCritText0 critText0 width-70.2880859375" y="63.5" x="400" font-size="11" id="task3-text">4. Modify data </text><text class="taskText taskText0 width-81.109375" y="63.5" x="492.5" font-size="11" id="task4-text">5. Answer dialog </text><text class="taskText taskText0 critText0 width-113.10223388671875" y="63.5" x="632" font-size="11" id="task5-text">6. Work on invalid data </text></g><g><text class="sectionTitle sectionTitle0" font-size="11" y="62" x="10" dy="0em"><tspan x="10" alignment-baseline="central">EDT</tspan></text><text class="sectionTitle sectionTitle1" font-size="11" y="86" x="10" dy="0em"><tspan x="10" alignment-baseline="central">BGT</tspan></text></g><g class="today"><line class="today" y2="123" y1="25" x2="160997948259" x1="160997948259"></line></g><text class="titleText" y="25" x="400"></text></svg><p id="z7olnq5_237" class="article__p h2-related">Passing the modality state solves this problem:</p><ol class="article__list list _decimal h2-related" id="z7olnq5_238" type="1"><li class="list__item" id="z7olnq5_264"><p class="article__p child">A user action is started.</p></li><li class="list__item" id="z7olnq5_265"><p class="article__p child">In the meantime, another operation is scheduled on EDT with <code class="code" id="z7olnq5_271">Application.invokeLater()</code> (supporting modality state). The operation is scheduled with <code class="code" id="z7olnq5_272">ModalityState.defaultModalityState()</code> (see the table below for other helper methods).</p></li><li class="list__item" id="z7olnq5_266"><p class="article__p child">The action from 1. now shows a dialog asking a <span class="control" id="z7olnq5_273">Yes</span>/<span class="control" id="z7olnq5_274">No</span> question. This adds a modal dialog to the modality state stack.</p></li><li class="list__item" id="z7olnq5_267"><p class="article__p child">While the dialog is shown, the scheduled operation waits as it was scheduled with a "lower" modality state than the current state with an additional dialog.</p></li><li class="list__item" id="z7olnq5_268"><p class="article__p child">The user clicks <span class="control" id="z7olnq5_275">Yes</span> or <span class="control" id="z7olnq5_276">No</span> in the dialog, and it executes some code based on the answer.</p></li><li class="list__item" id="z7olnq5_269"><p class="article__p child">The code is executed on data in the same state as before the dialog was shown.</p></li><li class="list__item" id="z7olnq5_270"><p class="article__p child">The operation from 1. is executed now without interfering with the user's action.</p></li></ol><svg aria-roledescription="gantt" role="graphics-document document" viewBox="0 0 800 148" xmlns="http://www.w3.org/2000/svg" width="100%" id="mermaid" class="h2-related" style="max-width: 800px;"><g></g><g text-anchor="middle" font-family="sans-serif" font-size="10" fill="none" transform="translate(75, 98)" class="grid"><path d="M0.5,-63V0.5H650.5V-63" stroke="currentColor" class="domain"></path><g transform="translate(0.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(46.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(93.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(139.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(186.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(232.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(279.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(325.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(371.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(418.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(464.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(511.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(557.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(604.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(650.5,0)" opacity="1" class="tick"><line y2="-63" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g></g><g><rect class="section section0" height="24" width="762.5" y="48" x="0"></rect><rect class="section section1" height="24" width="762.5" y="72" x="0"></rect></g><g><rect class="task task0" transform-origin="168px 60px" height="20" width="186" y="50" x="75" ry="3" rx="3" id="task1"></rect><rect class="task active1" transform-origin="214.5px 84px" height="20" width="93" y="74" x="168" ry="3" rx="3" id="task6"></rect><rect class="task task0" transform-origin="307.5px 60px" height="20" width="93" y="50" x="261" ry="3" rx="3" id="task2"></rect><rect class="task done1" transform-origin="353.5px 84px" height="20" width="185" y="74" x="261" ry="3" rx="3" id="task7"></rect><rect class="task task0" transform-origin="400px 60px" height="20" width="92" y="50" x="354" ry="3" rx="3" id="task3"></rect><rect class="task task0" transform-origin="539px 60px" height="20" width="186" y="50" x="446" ry="3" rx="3" id="task4"></rect><rect class="task active0" transform-origin="678.5px 60px" height="20" width="93" y="50" x="632" ry="3" rx="3" id="task5"></rect><text class="taskText taskText0 width-68.234375" y="63.5" x="168" font-size="11" id="task1-text">1. Start action </text><text class="taskText taskText1 activeText1 width-76.8125" y="87.5" x="214.5" font-size="11" id="task6-text">2. invokeLater() </text><text class="taskText taskText0 width-72.5" y="63.5" x="307.5" font-size="11" id="task2-text">3. Show dialog </text><text class="taskText taskText1 doneText1 width-111.453125" y="87.5" x="353.5" font-size="11" id="task7-text">4. Wait for dialog close </text><text class="taskText taskText0 width-81.109375" y="63.5" x="400" font-size="11" id="task3-text">5. Answer dialog </text><text class="taskText taskText0 width-115.53533935546875" y="63.5" x="539" font-size="11" id="task4-text">6. Work on correct data </text><text class="taskText taskText0 activeText0 width-70.2880859375" y="63.5" x="678.5" font-size="11" id="task5-text">7. Modify data </text></g><g><text class="sectionTitle sectionTitle0" font-size="11" y="62" x="10" dy="0em"><tspan x="10" alignment-baseline="central">EDT</tspan></text><text class="sectionTitle sectionTitle1" font-size="11" y="86" x="10" dy="0em"><tspan x="10" alignment-baseline="central">BGT</tspan></text></g><g class="today"><line class="today" y2="123" y1="25" x2="160997948263" x1="160997948263"></line></g><text class="titleText" y="25" x="400"></text></svg><p id="z7olnq5_240" class="article__p h2-related">The following table presents methods providing useful modality states to be passed to <code class="code" id="z7olnq5_277">Application.invokeLater()</code>:</p><div class="table h2-related"><div class="table__wrapper table__wrapper--wide table__wrapper--without-scroll"><table class="table__content table__content--wide" id="z7olnq5_241"><thead class="table__thead undefined"><tr class="table__tr ijRowHead" id="z7olnq5_278"><th class="table__th undefined" id="z7olnq5_284"><p class="article__p"><a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/core-api/src/com/intellij/openapi/application/ModalityState.java" data-test="external-link " rel="" class="link link--external" id="z7olnq5_286"><code class="code" id="z7olnq5_287">ModalityState</code></a></p></th><th class="table__th undefined" id="z7olnq5_285"><p class="article__p">Description</p></th></tr></thead><tbody class="table__tbody undefined"><tr class="table__tr undefined" id="z7olnq5_279"><td class="table__td undefined" id="z7olnq5_288"><p id="z7olnq5_290" class="article__p child"><code class="code" id="z7olnq5_292">defaultModalityState()</code></p><p id="z7olnq5_291" class="article__p child"><span class="emphasis" id="z7olnq5_293">Used if none specified</span></p></td><td class="table__td undefined" id="z7olnq5_289"><p id="z7olnq5_294" class="article__p child">If invoked from EDT, it uses the <code class="code" id="z7olnq5_297">ModalityState.current()</code>.</p><p id="z7olnq5_295" class="article__p child">If invoked from a background process started with <code class="code" id="z7olnq5_298">ProgressManager</code>, the operation can be executed in the same dialog that the process started.</p><p id="z7olnq5_296" class="article__p child"><span class="control" id="z7olnq5_299">This is the optimal choice in most cases.</span></p></td></tr><tr class="table__tr undefined" id="z7olnq5_280"><td class="table__td undefined" id="z7olnq5_300"><p class="article__p child"><code class="code" id="z7olnq5_302">current()</code></p></td><td class="table__td undefined" id="z7olnq5_301"><p class="article__p child">The operation can be executed when the modality state stack doesn't grow since the operation was scheduled.</p></td></tr><tr class="table__tr undefined" id="z7olnq5_281"><td class="table__td undefined" id="z7olnq5_303"><p class="article__p child"><code class="code" id="z7olnq5_305">stateForComponent()</code></p></td><td class="table__td undefined" id="z7olnq5_304"><p class="article__p child">The operation can be executed when the topmost shown dialog is the one that contains the specified component or is one of its parent dialogs.</p></td></tr><tr class="table__tr undefined" id="z7olnq5_282"><td class="table__td undefined" id="z7olnq5_306"><p id="z7olnq5_308" class="article__p child"><code class="code" id="z7olnq5_310">nonModal()</code> or</p><p id="z7olnq5_309" class="article__p child"><code class="code" id="z7olnq5_311">NON_MODAL</code></p></td><td class="table__td undefined" id="z7olnq5_307"><p class="article__p child">The operation will be executed after all modal dialogs are closed. If any of the open (unrelated) projects displays a per-project modal dialog, the operation will be performed after the dialog is closed.</p></td></tr><tr class="table__tr undefined" id="z7olnq5_283"><td class="table__td undefined" id="z7olnq5_312"><p class="article__p child"><code class="code" id="z7olnq5_314">any()</code></p></td><td class="table__td undefined" id="z7olnq5_313"><p class="article__p child">The operation will be executed as soon as possible regardless of modal dialogs (the same as with <code class="code" id="z7olnq5_315">SwingUtilities.invokeLater()</code>). It can be used for scheduling only pure UI operations. Modifying PSI, VFS, or project model is prohibited. </p><p id="z7olnq5_316" class="article__p child"><span class="control" id="z7olnq5_317">Don't use it unless absolutely needed.</span></p></td></tr></tbody></table></div></div><blockquote class="prompt h2-related" data-test-id="aoGLMjU3rgE7gYMN9BREC"><h3 class="a11y-title">note</h3><div class="prompt__wrapper prompt__wrapper--type-note" data-test="prompt"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_m prompt__icon"><path d="M21 12a9 9 0 1 1-9-9 9 9 0 0 1 9 9zM10.5 7.5A1.5 1.5 0 1 0 12 6a1.5 1.5 0 0 0-1.5 1.5zm-.5 3.54v1h1V18h2v-6a.96.96 0 0 0-.96-.96z"></path></svg><div class="prompt__content"><p id="z7olnq5_318" class="article__p child">If EDT activity needs to access a <a data-test="internal-link link-with-popover" rel="" class="link" id="z7olnq5_319" href="indexing-and-psi-stubs.html">file-based index</a> (for example, it is doing any project-wide PSI analysis, resolves references, or performs other tasks depending on indexes), use <a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/core-api/src/com/intellij/openapi/project/DumbService.kt" data-test="external-link " rel="" class="link link--external" id="z7olnq5_320"><code class="code" id="z7olnq5_322">DumbService.smartInvokeLater()</code></a>. This API also supports <code class="code" id="z7olnq5_321">ModalityState</code> and runs the operation after all possible indexing processes have been completed.</p></div></div></blockquote></section><section class="chapter h1-related"><h2 id="read-action-cancellability" data-toc="read-action-cancellability" class="article__h2"><span class="title"><span class="title__content">Read Action Cancellability</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#read-action-cancellability"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#read-action-cancellability"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_s permalink__icon permalink__icon--size-s"><path d="M21.207 4.793a4.536 4.536 0 0 0-6.414 0l-4.5 4.5 1.414 1.414 4.5-4.5a2.536 2.536 0 0 1 3.586 3.586l-4.5 4.5 1.414 1.414 4.5-4.5a4.536 4.536 0 0 0 0-6.414z"></path><path d="M8.328 16.258a2.536 2.536 0 1 1-3.586-3.586l4.5-4.5-1.414-1.414-4.5 4.5a4.535 4.535 0 0 0 6.414 6.414l4.5-4.5-1.414-1.414z"></path></svg></span></a></span></h2><p id="z7olnq5_323" class="article__p h2-related">BGT shouldn't hold read locks for a long time. The reason is that if EDT needs a write action (for example, the user types something in the editor), it must be acquired as soon as possible. Otherwise, the UI will freeze until all BGTs have released their read actions. The following diagram presents this problem:</p><svg aria-roledescription="gantt" role="graphics-document document" viewBox="0 0 800 172" xmlns="http://www.w3.org/2000/svg" width="100%" id="mermaid" class="h2-related" style="max-width: 800px;"><g></g><g text-anchor="middle" font-family="sans-serif" font-size="10" fill="none" transform="translate(75, 122)" class="grid"><path d="M0.5,-87V0.5H650.5V-87" stroke="currentColor" class="domain"></path><g transform="translate(0.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(65.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(130.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(195.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(260.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(325.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(390.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(455.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(520.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(585.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(650.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g></g><g><rect class="section section0" height="24" width="762.5" y="48" x="0"></rect><rect class="section section1" height="24" width="762.5" y="72" x="0"></rect><rect class="section section1" height="24" width="762.5" y="96" x="0"></rect></g><g><rect class="task task0" transform-origin="335px 60px" height="20" width="520" y="50" x="75" ry="3" rx="3" id="task1"></rect><rect class="task done1" transform-origin="400px 84px" height="20" width="390" y="74" x="205" ry="3" rx="3" id="task2"></rect><rect class="task crit1" transform-origin="465px 108px" height="20" width="520" y="98" x="205" ry="3" rx="3" id="task4"></rect><rect class="task task1" transform-origin="660px 84px" height="20" width="130" y="74" x="595" ry="3" rx="3" id="task3"></rect><text class="taskText taskText0 width-102.625" y="63.5" x="335" font-size="11" id="task1-text">very long read action </text><text class="taskText taskText1 doneText1 width-158.96875" y="87.5" x="400" font-size="11" id="task2-text">write action (waiting for the lock) </text><text class="taskText taskText1 critText1 width-44.859375" y="111.5" x="465" font-size="11" id="task4-text">UI freeze </text><text class="taskText taskText1 width-114.6875" y="87.5" x="660" font-size="11" id="task3-text">write action (executing) </text></g><g><text class="sectionTitle sectionTitle0" font-size="11" y="62" x="10" dy="0em"><tspan x="10" alignment-baseline="central">BGT</tspan></text><text class="sectionTitle sectionTitle1" font-size="11" y="98" x="10" dy="0em"><tspan x="10" alignment-baseline="central">EDT</tspan></text></g><g class="today"><line class="today" y2="147" y1="25" x2="225397127543" x1="225397127543"></line></g><text class="titleText" y="25" x="400"></text></svg><p id="z7olnq5_325" class="article__p h2-related">Sometimes, it is required to run a long read action, and it isn't possible to speed it up. In such a case, the recommended approach is to cancel the read action whenever there is a write action about to occur and restart that read action later from scratch:</p><svg aria-roledescription="gantt" role="graphics-document document" viewBox="0 0 800 172" xmlns="http://www.w3.org/2000/svg" width="100%" id="mermaid" class="h2-related" style="max-width: 800px;"><g></g><g text-anchor="middle" font-family="sans-serif" font-size="10" fill="none" transform="translate(75, 122)" class="grid"><path d="M0.5,-87V0.5H650.5V-87" stroke="currentColor" class="domain"></path><g transform="translate(0.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(65.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(130.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(195.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(260.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(325.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(390.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(455.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(520.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(585.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g><g transform="translate(650.5,0)" opacity="1" class="tick"><line y2="-87" stroke="currentColor"></line><text font-size="10" stroke="none" dy="1em" y="3" fill="#000" style="text-anchor: middle;"></text></g></g><g><rect class="section section0" height="24" width="762.5" y="48" x="0"></rect><rect class="section section0" height="24" width="762.5" y="72" x="0"></rect><rect class="section section1" height="24" width="762.5" y="96" x="0"></rect></g><g><rect class="task task0" transform-origin="140px 60px" height="20" width="130" y="50" x="75" ry="3" rx="3" id="task1"></rect><rect class="task milestone crit0" transform-origin="205px 84px" height="20" width="20" y="74" x="195" ry="3" rx="3" id="task3"></rect><rect class="task task1" transform-origin="270px 108px" height="20" width="130" y="98" x="205" ry="3" rx="3" id="task5"></rect><rect class="task task0" transform-origin="530px 60px" height="20" width="390" y="50" x="335" ry="3" rx="3" id="task2"></rect><rect class="task milestone task0" transform-origin="335px 84px" height="20" width="20" y="74" x="325" ry="3" rx="3" id="task4"></rect><text class="taskText taskText0 width-102.625" y="63.5" x="140" font-size="11" id="task1-text">very long read action </text><text class="taskTextOutsideRight taskTextOutside0 critText0 milestoneText width-62.03125" y="87.5" x="220" font-size="11" id="task3-text">RA canceled </text><text class="taskText taskText1 width-56.921875" y="111.5" x="270" font-size="11" id="task5-text">write action </text><text class="taskText taskText0 width-171.4375" y="63.5" x="530" font-size="11" id="task2-text">very long read action (2nd attempt) </text><text class="taskTextOutsideRight taskTextOutside0 milestoneText width-125.3125" y="87.5" x="350" font-size="11" id="task4-text">RA restarted from scratch </text></g><g><text class="sectionTitle sectionTitle0" font-size="11" y="74" x="10" dy="0em"><tspan x="10" alignment-baseline="central">BGT</tspan></text><text class="sectionTitle sectionTitle1" font-size="11" y="110" x="10" dy="0em"><tspan x="10" alignment-baseline="central">EDT</tspan></text></g><g class="today"><line class="today" y2="147" y1="25" x2="225397127552" x1="225397127552"></line></g><text class="titleText" y="25" x="400"></text></svg><p id="z7olnq5_327" class="article__p h2-related">In this case, the EDT won't be blocked and the UI freeze is avoided. The total execution time of the read action will be longer due to multiple attempts, but not affecting the UI responsiveness is more important.</p><p id="z7olnq5_328" class="article__p h2-related">The canceling approach is widely used in various areas of the IntelliJ Platform: editor highlighting, code completion, "go to class/file/…" actions all work like this. Read the <a data-test="internal-link link-with-popover" rel="" class="link" id="z7olnq5_330" href="background-processes.html">Background Processes</a> section for more details.</p><section class="chapter h2-related"><h3 id="cancellable-read-actions-api" data-toc="cancellable-read-actions-api" class="article__h3"><span class="title"><span class="title__content">Cancellable Read Actions API</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#cancellable-read-actions-api"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#cancellable-read-actions-api"><svg viewBox="0 0 16 16" class="wt-icon wt-icon_size_xs permalink__icon permalink__icon--size-xs"><path d="M14.094 3.801a3.093 3.093 0 0 0-4.373 0L6.653 6.87l.964.964 3.068-3.069A1.729 1.729 0 0 1 13.13 7.21l-3.068 3.069.964.964 3.068-3.068a3.093 3.093 0 0 0 0-4.374z"></path><path d="M5.313 11.618a1.729 1.729 0 0 1-2.445-2.445l3.068-3.068-.964-.964-3.068 3.068a3.092 3.092 0 0 0 4.373 4.374l3.069-3.069-.965-.964z"></path></svg></span></a></span></h3><blockquote class="prompt h3-related" data-test-id="PX8UwwA1_JKaDUTb8X56d"><h3 class="a11y-title">warning</h3><div class="prompt__wrapper prompt__wrapper--type-warning" data-test="prompt"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_m prompt__icon"><path d="M12.946 3.552L21.52 18.4c.424.735.33 1.6-.519 1.6H3.855c-.85 0-1.817-.865-1.392-1.6l8.573-14.848a1.103 1.103 0 0 1 1.91 0zm.545 12.948a1.5 1.5 0 1 0-1.5 1.5 1.5 1.5 0 0 0 1.5-1.5zM13 8h-2v5h2z"></path></svg><div class="prompt__content"><p id="z7olnq5_337" class="article__p child">Plugins targeting versions 2024.1+ should use Write Allowing Read Actions available in the <a data-test="internal-link " rel="" class="link" id="z7olnq5_338" href="coroutine-read-actions.html#coroutine-read-actions-api">Kotlin Coroutines Read Actions API</a>.</p></div></div></blockquote><p id="z7olnq5_332" class="article__p h3-related">To run a cancellable read action, use one of the available APIs:</p><ul class="article__list list _bullet h3-related" id="z7olnq5_333"><li class="list__item" id="z7olnq5_339"><p class="article__p child"><a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/core-api/src/com/intellij/openapi/application/ReadAction.java" data-test="external-link " rel="" class="link link--external" id="z7olnq5_341"><code class="code" id="z7olnq5_343">ReadAction.nonBlocking()</code></a> which returns <a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/core-api/src/com/intellij/openapi/application/NonBlockingReadAction.java" data-test="external-link " rel="" class="link link--external" id="z7olnq5_342"><code class="code" id="z7olnq5_344">NonBlockingReadAction</code></a> (NBRA). NBRA handles restarting the action out-of-the-box.</p></li><li class="list__item" id="z7olnq5_340"><p class="article__p child"><a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/core-api/src/com/intellij/openapi/application/ReadAction.java" data-test="external-link " rel="" class="link link--external" id="z7olnq5_345"><code class="code" id="z7olnq5_346">ReadAction.computeCancellable()</code></a> which computes the result immediately in the current thread or throws an exception if there is a running or requested write action.</p></li></ul><p id="z7olnq5_334" class="article__p h3-related">In both cases, when a read action is started and a write action occurs in the meantime, the read action is marked as canceled. Read actions must <a data-test="internal-link " rel="" class="link" id="z7olnq5_347" href="background-processes.html#handling-cancellation">check for cancellation</a> often enough to trigger actual cancellation. Although the cancellation mechanism may differ under the hood (<a data-test="internal-link " rel="" class="link" id="z7olnq5_348" href="background-processes.html#progress-api">Progress API</a> or <a data-test="internal-link link-with-popover" rel="" class="link" id="z7olnq5_349" href="kotlin-coroutines.html">Kotlin Coroutines</a>), the cancellation handling rules are the same in both cases.</p><p id="z7olnq5_335" class="article__p h3-related">Always check at the start of each read action if the <a data-test="internal-link " rel="" class="link" id="z7olnq5_350" href="/docs/intellij/threading-model.html#objects-validity">objects are still valid</a>, and if the whole operation still makes sense. With <code class="code" id="z7olnq5_351">ReadAction.nonBlocking()</code>, use <code class="code" id="z7olnq5_352">expireWith()</code> or <code class="code" id="z7olnq5_353">expireWhen()</code> for that.</p><blockquote class="prompt h3-related" data-test-id="Z8Mp3lIBj7THq7IBGpUz-"><h3 class="a11y-title">note</h3><div class="prompt__wrapper prompt__wrapper--type-note" data-test="prompt"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_m prompt__icon"><path d="M21 12a9 9 0 1 1-9-9 9 9 0 0 1 9 9zM10.5 7.5A1.5 1.5 0 1 0 12 6a1.5 1.5 0 0 0-1.5 1.5zm-.5 3.54v1h1V18h2v-6a.96.96 0 0 0-.96-.96z"></path></svg><div class="prompt__content"><p id="z7olnq5_354" class="article__p child">If NBRA needs to access a <a data-test="internal-link link-with-popover" rel="" class="link" id="z7olnq5_355" href="indexing-and-psi-stubs.html">file-based index</a> (for example, it is doing any project-wide PSI analysis, resolves references, or performs other tasks depending on indexes), use <code class="code" id="z7olnq5_356">ReadAction.nonBlocking(…).inSmartMode()</code>.</p></div></div></blockquote></section></section><section class="chapter h1-related"><h2 id="avoiding-ui-freezes" data-toc="avoiding-ui-freezes" class="article__h2"><span class="title"><span class="title__content">Avoiding UI Freezes</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#avoiding-ui-freezes"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#avoiding-ui-freezes"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_s permalink__icon permalink__icon--size-s"><path d="M21.207 4.793a4.536 4.536 0 0 0-6.414 0l-4.5 4.5 1.414 1.414 4.5-4.5a2.536 2.536 0 0 1 3.586 3.586l-4.5 4.5 1.414 1.414 4.5-4.5a4.536 4.536 0 0 0 0-6.414z"></path><path d="M8.328 16.258a2.536 2.536 0 1 1-3.586-3.586l4.5-4.5-1.414-1.414-4.5 4.5a4.535 4.535 0 0 0 6.414 6.414l4.5-4.5-1.414-1.414z"></path></svg></span></a></span></h2><section class="chapter h2-related"><h3 id="don-t-perform-long-operations-on-edt" data-toc="don-t-perform-long-operations-on-edt" class="article__h3"><span class="title"><span class="title__content">Don't Perform Long Operations on EDT</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#don-t-perform-long-operations-on-edt"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#don-t-perform-long-operations-on-edt"><svg viewBox="0 0 16 16" class="wt-icon wt-icon_size_xs permalink__icon permalink__icon--size-xs"><path d="M14.094 3.801a3.093 3.093 0 0 0-4.373 0L6.653 6.87l.964.964 3.068-3.069A1.729 1.729 0 0 1 13.13 7.21l-3.068 3.069.964.964 3.068-3.068a3.093 3.093 0 0 0 0-4.374z"></path><path d="M5.313 11.618a1.729 1.729 0 0 1-2.445-2.445l3.068-3.068-.964-.964-3.068 3.068a3.092 3.092 0 0 0 4.373 4.374l3.069-3.069-.965-.964z"></path></svg></span></a></span></h3><p id="z7olnq5_360" class="article__p h3-related">In particular, don't traverse <a data-test="internal-link link-with-popover" rel="" class="link" id="z7olnq5_365" href="virtual-file-system.html">VFS</a>, parse <a data-test="internal-link link-with-popover" rel="" class="link" id="z7olnq5_366" href="psi.html">PSI</a>, resolve <a data-test="internal-link link-with-popover" rel="" class="link" id="z7olnq5_367" href="psi-references.html">references,</a> or query <a data-test="internal-link link-with-popover" rel="" class="link" id="z7olnq5_368" href="indexing-and-psi-stubs.html">indexes</a>.</p><p id="z7olnq5_361" class="article__p h3-related">There are still some cases when the platform itself invokes such expensive code (for example, resolve in <code class="code" id="z7olnq5_369">AnAction.update()</code>), but these are being worked on. Meanwhile, try to speed up what you can in your plugin as it will be generally beneficial and will also improve background highlighting performance.</p><section class="chapter h3-related"><h4 id="action-update" data-toc="action-update" class="article__h4"><span class="title"><span class="title__content">Action Update</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#action-update"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#action-update"><svg viewBox="0 0 16 16" class="wt-icon wt-icon_size_xs permalink__icon permalink__icon--size-xs"><path d="M14.094 3.801a3.093 3.093 0 0 0-4.373 0L6.653 6.87l.964.964 3.068-3.069A1.729 1.729 0 0 1 13.13 7.21l-3.068 3.069.964.964 3.068-3.068a3.093 3.093 0 0 0 0-4.374z"></path><path d="M5.313 11.618a1.729 1.729 0 0 1-2.445-2.445l3.068-3.068-.964-.964-3.068 3.068a3.092 3.092 0 0 0 4.373 4.374l3.069-3.069-.965-.964z"></path></svg></span></a></span></h4><p id="z7olnq5_370" class="article__p h4-related">For implementations of <a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java" data-test="external-link " rel="" class="link link--external" id="z7olnq5_371"><code class="code" id="z7olnq5_374">AnAction</code></a>, plugin authors should specifically review the documentation of <code class="code" id="z7olnq5_372">AnAction.getActionUpdateThread()</code> in the <a data-test="internal-link link-with-popover" rel="" class="link" id="z7olnq5_373" href="basic-action-system.html">Actions</a> section as it describes how threading works for actions.</p></section><section class="chapter h3-related"><h4 id="minimize-write-actions-scope" data-toc="minimize-write-actions-scope" class="article__h4"><span class="title"><span class="title__content">Minimize Write Actions Scope</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#minimize-write-actions-scope"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#minimize-write-actions-scope"><svg viewBox="0 0 16 16" class="wt-icon wt-icon_size_xs permalink__icon permalink__icon--size-xs"><path d="M14.094 3.801a3.093 3.093 0 0 0-4.373 0L6.653 6.87l.964.964 3.068-3.069A1.729 1.729 0 0 1 13.13 7.21l-3.068 3.069.964.964 3.068-3.068a3.093 3.093 0 0 0 0-4.374z"></path><path d="M5.313 11.618a1.729 1.729 0 0 1-2.445-2.445l3.068-3.068-.964-.964-3.068 3.068a3.092 3.092 0 0 0 4.373 4.374l3.069-3.069-.965-.964z"></path></svg></span></a></span></h4><p id="z7olnq5_375" class="article__p h4-related">Write actions currently <a data-test="internal-link " rel="" class="link" id="z7olnq5_376" href="/docs/intellij/threading-model.html#locks-and-edt">have to happen on EDT</a>. To speed them up, as much as possible should be moved out of the write action into a preparation step which can be then invoked in the <a data-test="internal-link link-with-popover" rel="" class="link" id="z7olnq5_377" href="background-processes.html">background</a> or inside an <a data-test="internal-link " rel="" class="link" id="z7olnq5_378" href="/docs/intellij/threading-model.html#cancellable-read-actions-api">NBRA</a>.</p></section><section class="chapter h3-related"><h4 id="slow-operations-on-edt-assertion" data-toc="slow-operations-on-edt-assertion" class="article__h4"><span class="title"><span class="title__content">Slow Operations on EDT Assertion</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#slow-operations-on-edt-assertion"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#slow-operations-on-edt-assertion"><svg viewBox="0 0 16 16" class="wt-icon wt-icon_size_xs permalink__icon permalink__icon--size-xs"><path d="M14.094 3.801a3.093 3.093 0 0 0-4.373 0L6.653 6.87l.964.964 3.068-3.069A1.729 1.729 0 0 1 13.13 7.21l-3.068 3.069.964.964 3.068-3.068a3.093 3.093 0 0 0 0-4.374z"></path><path d="M5.313 11.618a1.729 1.729 0 0 1-2.445-2.445l3.068-3.068-.964-.964-3.068 3.068a3.092 3.092 0 0 0 4.373 4.374l3.069-3.069-.965-.964z"></path></svg></span></a></span></h4><p id="z7olnq5_379" class="article__p h4-related">Some of the long operations are reported by <a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/core-api/src/com/intellij/util/SlowOperations.java" data-test="external-link " rel="" class="link link--external" id="z7olnq5_380"><code class="code" id="z7olnq5_386">SlowOperations.assertSlowOperationsAreAllowed()</code></a>. According to its Javadoc, they must be moved to BGT. This can be achieved with the techniques mentioned in the Javadoc, <a data-test="internal-link link-with-popover" rel="" class="link" id="z7olnq5_381" href="background-processes.html">background processes</a>, <a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/core-api/src/com/intellij/openapi/application/Application.java" data-test="external-link " rel="" class="link link--external" id="z7olnq5_382"><code class="code" id="z7olnq5_387">Application.executeOnPooledThread()</code></a>, or <a data-test="internal-link link-with-popover" rel="" class="link" id="z7olnq5_383" href="kotlin-coroutines.html">coroutines</a> (recommended for plugins targeting 2024.1+). Note that the assertion is enabled in IDE EAP versions, <a data-test="internal-link link-with-popover" rel="" class="link" id="z7olnq5_384" href="enabling-internal.html">internal mode</a>, or <a data-test="internal-link link-with-popover" rel="" class="link" id="z7olnq5_385" href="ide-development-instance.html">development instance</a>, and regular users don't see them in the IDE. This will change in the future, so fixing these exceptions is required.</p></section></section><section class="chapter h2-related"><h3 id="event-listeners" data-toc="event-listeners" class="article__h3"><span class="title"><span class="title__content">Event Listeners</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#event-listeners"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#event-listeners"><svg viewBox="0 0 16 16" class="wt-icon wt-icon_size_xs permalink__icon permalink__icon--size-xs"><path d="M14.094 3.801a3.093 3.093 0 0 0-4.373 0L6.653 6.87l.964.964 3.068-3.069A1.729 1.729 0 0 1 13.13 7.21l-3.068 3.069.964.964 3.068-3.068a3.093 3.093 0 0 0 0-4.374z"></path><path d="M5.313 11.618a1.729 1.729 0 0 1-2.445-2.445l3.068-3.068-.964-.964-3.068 3.068a3.092 3.092 0 0 0 4.373 4.374l3.069-3.069-.965-.964z"></path></svg></span></a></span></h3><p id="z7olnq5_388" class="article__p h3-related">Listeners mustn't perform any heavy operations. Ideally, they should only clear some caches.</p><p id="z7olnq5_389" class="article__p h3-related">It is also possible to schedule background processing of events. In such cases, be prepared that some new events might be delivered before the background processing starts – and thus the world might have changed by that moment or even in the middle of background processing. Consider using <a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/ide-core/src/com/intellij/util/ui/update/MergingUpdateQueue.kt" data-test="external-link " rel="" class="link link--external" id="z7olnq5_390"><code class="code" id="z7olnq5_392">MergingUpdateQueue</code></a> and <a data-test="internal-link " rel="" class="link" id="z7olnq5_391" href="/docs/intellij/threading-model.html#cancellable-read-actions-api">NBRA</a> to mitigate these issues.</p></section><section class="chapter h2-related"><h3 id="vfs-events" data-toc="vfs-events" class="article__h3"><span class="title"><span class="title__content">VFS Events</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#vfs-events"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#vfs-events"><svg viewBox="0 0 16 16" class="wt-icon wt-icon_size_xs permalink__icon permalink__icon--size-xs"><path d="M14.094 3.801a3.093 3.093 0 0 0-4.373 0L6.653 6.87l.964.964 3.068-3.069A1.729 1.729 0 0 1 13.13 7.21l-3.068 3.069.964.964 3.068-3.068a3.093 3.093 0 0 0 0-4.374z"></path><path d="M5.313 11.618a1.729 1.729 0 0 1-2.445-2.445l3.068-3.068-.964-.964-3.068 3.068a3.092 3.092 0 0 0 4.373 4.374l3.069-3.069-.965-.964z"></path></svg></span></a></span></h3><p id="z7olnq5_393" class="article__p h3-related">Massive batches of VFS events can be pre-processed in the background with <a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/core-api/src/com/intellij/openapi/vfs/AsyncFileListener.java" data-test="external-link " rel="" class="link link--external" id="z7olnq5_394"><code class="code" id="z7olnq5_395">AsyncFileListener</code></a>.</p></section></section><section class="chapter h1-related"><h2 id="faq" data-toc="faq" class="article__h2"><span class="title"><span class="title__content">FAQ</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#faq"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#faq"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_s permalink__icon permalink__icon--size-s"><path d="M21.207 4.793a4.536 4.536 0 0 0-6.414 0l-4.5 4.5 1.414 1.414 4.5-4.5a2.536 2.536 0 0 1 3.586 3.586l-4.5 4.5 1.414 1.414 4.5-4.5a4.536 4.536 0 0 0 0-6.414z"></path><path d="M8.328 16.258a2.536 2.536 0 1 1-3.586-3.586l4.5-4.5-1.414-1.414-4.5 4.5a4.535 4.535 0 0 0 6.414 6.414l4.5-4.5-1.414-1.414z"></path></svg></span></a></span></h2><section class="chapter h2-related"><h3 id="how-to-check-whether-the-current-thread-is-the-edtui-thread" data-toc="how-to-check-whether-the-current-thread-is-the-edtui-thread" class="article__h3"><span class="title"><span class="title__content">How to check whether the current thread is the EDT/UI thread?</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#how-to-check-whether-the-current-thread-is-the-edtui-thread"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#how-to-check-whether-the-current-thread-is-the-edtui-thread"><svg viewBox="0 0 16 16" class="wt-icon wt-icon_size_xs permalink__icon permalink__icon--size-xs"><path d="M14.094 3.801a3.093 3.093 0 0 0-4.373 0L6.653 6.87l.964.964 3.068-3.069A1.729 1.729 0 0 1 13.13 7.21l-3.068 3.069.964.964 3.068-3.068a3.093 3.093 0 0 0 0-4.374z"></path><path d="M5.313 11.618a1.729 1.729 0 0 1-2.445-2.445l3.068-3.068-.964-.964-3.068 3.068a3.092 3.092 0 0 0 4.373 4.374l3.069-3.069-.965-.964z"></path></svg></span></a></span></h3><p id="z7olnq5_399" class="article__p h3-related">Use <code class="code" id="z7olnq5_401">Application.isDispatchThread()</code>.</p><p id="z7olnq5_400" class="article__p h3-related">If code must be invoked on EDT and the current thread can be EDT or BGT, use <a href="https://github.com/JetBrains/intellij-community/tree/idea/243.22562.145/platform/util/ui/src/com/intellij/util/ui/UIUtil.java" data-test="external-link " rel="" class="link link--external" id="z7olnq5_402"><code class="code" id="z7olnq5_403">UIUtil.invokeLaterIfNeeded()</code></a>. If the current thread is EDT, this method will run code immediately, or will schedule a later invocation if the current thread is BGT.</p></section><section class="chapter h2-related"><h3 id="why-write-actions-are-currently-allowed-only-on-edt" data-toc="why-write-actions-are-currently-allowed-only-on-edt" class="article__h3"><span class="title"><span class="title__content">Why write actions are currently allowed only on EDT?</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#why-write-actions-are-currently-allowed-only-on-edt"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#why-write-actions-are-currently-allowed-only-on-edt"><svg viewBox="0 0 16 16" class="wt-icon wt-icon_size_xs permalink__icon permalink__icon--size-xs"><path d="M14.094 3.801a3.093 3.093 0 0 0-4.373 0L6.653 6.87l.964.964 3.068-3.069A1.729 1.729 0 0 1 13.13 7.21l-3.068 3.069.964.964 3.068-3.068a3.093 3.093 0 0 0 0-4.374z"></path><path d="M5.313 11.618a1.729 1.729 0 0 1-2.445-2.445l3.068-3.068-.964-.964-3.068 3.068a3.092 3.092 0 0 0 4.373 4.374l3.069-3.069-.965-.964z"></path></svg></span></a></span></h3><p id="z7olnq5_404" class="article__p h3-related">Reading data model was often performed on EDT to display results in the UI. The IntelliJ Platform is more than 20 years old, and in its beginnings Java didn't offer features like generics and lambdas. Code that acquired read locks was very verbose. For convenience, it was decided that reading data can be done on EDT without read locks (even implicitly acquired).</p><p id="z7olnq5_405" class="article__p h3-related">The consequence of this was that writing had to be allowed only on EDT to avoid read/write conflicts. The nature of EDT provided this possibility out-of-the-box due to being a single thread. Event queue guaranteed that reads and writes were ordered and executed one by one and couldn't interweave.</p></section><section class="chapter h2-related"><h3 id="why-can-write-intent-lock-be-acquired-from-any-thread-but-write-lock-only-from-edt" data-toc="why-can-write-intent-lock-be-acquired-from-any-thread-but-write-lock-only-from-edt" class="article__h3"><span class="title"><span class="title__content">Why can write intent lock be acquired from any thread but write lock only from EDT?</span><a data-test="internal-link permalink" rel="" class="link-nude permalink" href="/docs/intellij/threading-model.html#why-can-write-intent-lock-be-acquired-from-any-thread-but-write-lock-only-from-edt"><span data-clipboard-text="https://plugins.jetbrains.com/docs/intellij/threading-model.html#why-can-write-intent-lock-be-acquired-from-any-thread-but-write-lock-only-from-edt"><svg viewBox="0 0 16 16" class="wt-icon wt-icon_size_xs permalink__icon permalink__icon--size-xs"><path d="M14.094 3.801a3.093 3.093 0 0 0-4.373 0L6.653 6.87l.964.964 3.068-3.069A1.729 1.729 0 0 1 13.13 7.21l-3.068 3.069.964.964 3.068-3.068a3.093 3.093 0 0 0 0-4.374z"></path><path d="M5.313 11.618a1.729 1.729 0 0 1-2.445-2.445l3.068-3.068-.964-.964-3.068 3.068a3.092 3.092 0 0 0 4.373 4.374l3.069-3.069-.965-.964z"></path></svg></span></a></span></h3><p id="z7olnq5_406" class="article__p h3-related">In the current platform state, technically, write intent lock can be acquired on any thread (it is done only on EDT in practice), but write lock can be acquired only on EDT.</p><p id="z7olnq5_407" class="article__p h3-related">Write intent lock was introduced as a "replacement" for EDT in the context of acquiring write lock. Instead of allowing to acquire write lock on EDT only, it was planned to make it possible to acquire it from under write intent lock on any thread. Write intent lock provides read access that was also available on EDT. This behavior wasn't enabled in production, and the planned locking mechanism has changed. It is planned to allow for acquiring write lock from any thread, even without a write intent lock. Write intent lock will be still available and will allow performing read sessions finished with data writing.</p><blockquote class="prompt h3-related" data-test-id="lnz31KRs2k_tuVa_i18QG"><h3 class="a11y-title">note</h3><div class="prompt__wrapper prompt__wrapper--type-note" data-test="prompt"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_m prompt__icon"><path d="M21 12a9 9 0 1 1-9-9 9 9 0 0 1 9 9zM10.5 7.5A1.5 1.5 0 1 0 12 6a1.5 1.5 0 0 0-1.5 1.5zm-.5 3.54v1h1V18h2v-6a.96.96 0 0 0-.96-.96z"></path></svg><div class="prompt__content"><div class="prompt__title">Something missing?</div><p id="z7olnq5_411" class="article__p child">If a topic you are interested in is not covered in the above sections, let us know via the <span class="control" id="z7olnq5_413">Was this page helpful?</span> feedback form below or <a data-test="internal-link " rel="" class="link" id="z7olnq5_414" href="getting-help.html#problems-with-the-guide">other channels</a>.</p><p id="z7olnq5_412" class="article__p child">Please be specific about the topics and reasons for adding them, and leave your email in case we need more details. Thanks for your feedback!</p></div></div></blockquote></section></section><div data-feedback-placeholder="true" class="h1-related"></div></div><div class="layout layout--scroll-element" data-test="layout"><div class="feedback"><div class="feedback__block" data-test="feedback-left"><p class="feedback__text">Thanks for your feedback!</p></div><div class="feedback__block feedback__block--active" data-test="feedback"><div align-items="center" class="wt-row wt-row_size_xs wt-row_wide wt-row_wrap wt-row_justify_start"><div class="wt-col-inline feedback__text">Was this page helpful?</div><div class="wt-col-inline"><button data-test="feedback-yes" type="button" class="_main_joawza_17 _modeOutline_joawza_356 _sizeS_joawza_92 _alignIconLeft_joawza_77 _light_joawza_59 feedback__button">Yes</button><button data-test="feedback-no" type="button" class="_main_joawza_17 _modeOutline_joawza_356 _sizeS_joawza_92 _alignIconLeft_joawza_77 _light_joawza_59 feedback__button">No</button></div></div></div></div></div></article><aside class="layout" data-test="layout"><div class="stretch__wrapper app__virtual-toc-sidebar"><div class="stretch" data-test="virtual-toc-sidebar" style="height: auto;"><div class="layout layout--scroll-container app__virtual-toc-scroll-disabler" data-test="scroller"><div class="layout layout--scroll-element" data-test="layout"><ul class="toc app__virtual-toc app__virtual-toc--bordered" data-test="virtual-toc"><li data-test="virtual-toc-header" class="toc__virtual-toc-header"><div class="toc-item toc-item--selected toc-item--theme-light" to="" data-test="toc-item--selected" style="padding-left: 16px;"><svg viewBox="-5 -3 24 24" data-test="toc-expander" class="wt-icon wt-icon_size_xs toc-icon toc-icon--opened toc-icon--theme-light"><path d="M11 9l-6 5.25V3.75z"></path></svg> On this page</div></li><li data-toc-scroll="threading_model" class="toc-node toc-node--selected toc-node--theme-light" data-test="toc-node--selected"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html" style="padding-left: 0px;"> Threading Model</a></li><li data-toc-scroll="read-write-lock" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#read-write-lock" style="padding-left: 0px;"> Read-Write Lock</a></li><li data-toc-scroll="locks-and-edt" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#locks-and-edt" style="padding-left: 16px;"> Locks and EDT</a></li><li data-toc-scroll="accessing-data" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#accessing-data" style="padding-left: 0px;"> Accessing Data</a></li><li data-toc-scroll="read-actions" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#read-actions" style="padding-left: 16px;"> Read Actions</a></li><li data-toc-scroll="write-actions" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#write-actions" style="padding-left: 16px;"> Write Actions</a></li><li data-toc-scroll="invoking-operations-on-edt-and-modality" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#invoking-operations-on-edt-and-modality" style="padding-left: 0px;"> Invoking Operations on EDT and Modality</a></li><li data-toc-scroll="read-action-cancellability" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#read-action-cancellability" style="padding-left: 0px;"> Read Action Cancellability</a></li><li data-toc-scroll="cancellable-read-actions-api" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#cancellable-read-actions-api" style="padding-left: 16px;"> Cancellable Read Actions API</a></li><li data-toc-scroll="avoiding-ui-freezes" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#avoiding-ui-freezes" style="padding-left: 0px;"> Avoiding UI Freezes</a></li><li data-toc-scroll="don-t-perform-long-operations-on-edt" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#don-t-perform-long-operations-on-edt" style="padding-left: 16px;"> Don't Perform Long Operations on EDT</a></li><li data-toc-scroll="event-listeners" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#event-listeners" style="padding-left: 16px;"> Event Listeners</a></li><li data-toc-scroll="vfs-events" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#vfs-events" style="padding-left: 16px;"> VFS Events</a></li><li data-toc-scroll="faq" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#faq" style="padding-left: 0px;"> FAQ</a></li><li data-toc-scroll="how-to-check-whether-the-current-thread-is-the-edtui-thread" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#how-to-check-whether-the-current-thread-is-the-edtui-thread" style="padding-left: 16px;"> How to check whether the current thread is the EDT/UI thread?</a></li><li data-toc-scroll="why-write-actions-are-currently-allowed-only-on-edt" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#why-write-actions-are-currently-allowed-only-on-edt" style="padding-left: 16px;"> Why write actions are currently allowed only on EDT?</a></li><li data-toc-scroll="why-can-write-intent-lock-be-acquired-from-any-thread-but-write-lock-only-from-edt" class="toc-node toc-node--theme-light" data-test="toc-node"><a data-test="internal-link toc-item" class="toc-item toc-item--anchor toc-item--theme-light" href="/docs/intellij/threading-model.html#why-can-write-intent-lock-be-acquired-from-any-thread-but-write-lock-only-from-edt" style="padding-left: 16px;"> Why can write intent lock be acquired from any thread but write lock only from EDT?</a></li></ul></div></div></div></div></aside></div><div class="layout layout--container-content layout--scroll-element" data-test="layout"><nav class="navigation-links"><a data-test="internal-link prev-page" class="navigation-links__prev" href="disposers.html"><svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_m navigation-links__prev-icon"><path d="M2 11.857L10 5v5.857h11v2H10v5.857l-8-6.857z"></path></svg>Disposer and Disposable</a><a data-test="internal-link next-page" class="navigation-links__next" href="background-processes.html">Background Processes<svg viewBox="0 0 24 24" class="wt-icon wt-icon_size_m navigation-links__next-icon"><path d="M21 12l-8-6.857V11H2v2h11v5.857L21 12z"></path></svg></a></nav></div><div class="app__footer app__footer--preset-contrast"><footer class="layout layout--container-content" data-test="layout"><div class="footer" data-test="footer"><div class="footer__wrapper"><div class="" data-test="footer-socials" style="margin-bottom: 8px;"><a data-test="button" title="IntelliJ Platform Plugin SDK on Twitter" href="https://x.com/JBPlatform/" type="button" class="_main_joawza_17 _modeClear_joawza_434 _sizeS_joawza_92 _alignIconLeft_joawza_77 _dark_joawza_62 _withIcon_joawza_119 _withoutText_joawza_113"><svg viewBox="0 0 24 24" class="_icon_1lgbkjk_3 _dark_1lgbkjk_31 _sizeM_1lgbkjk_17 rs-text-3 rs-text-3_hardness_average rs-text-3_theme_dark _icon_joawza_525"><path d="M17.09 4h2.715l-5.93 6.777L20.851 20H15.39l-4.278-5.593L6.216 20H3.5l6.342-7.25L3.15 4h5.601l3.867 5.113L17.091 4zm-.952 14.375h1.504L7.934 5.54H6.32l9.818 12.836z"></path></svg></a><a data-test="button" title="IntelliJ Platform Plugin SDK Blog" href="https://blog.jetbrains.com/platform/" type="button" class="_main_joawza_17 _modeClear_joawza_434 _sizeS_joawza_92 _alignIconLeft_joawza_77 _dark_joawza_62 _withIcon_joawza_119 _withoutText_joawza_113"><svg viewBox="0 0 24 24" class="_icon_1lgbkjk_3 _dark_1lgbkjk_31 _sizeM_1lgbkjk_17 rs-text-3 rs-text-3_hardness_average rs-text-3_theme_dark _icon_joawza_525"><path d="M13.999 5a2 2 0 11-4 0 2 2 0 014 0zm4.348 3h2.656l.033 9.967h-2.988A6.624 6.624 0 0012.02 22a6.913 6.913 0 00-6.25-4H3.036V8H5.77a6.912 6.912 0 016.25 4 7.025 7.025 0 016.327-4z"></path></svg></a><a data-test="button" title="IntelliJ Platform Plugin SDK on YouTube" href="https://www.youtube.com/playlist?list=PLQ176FUIyIUZRWGCFY7G9V5zaM00THymY" type="button" class="_main_joawza_17 _modeClear_joawza_434 _sizeS_joawza_92 _alignIconLeft_joawza_77 _dark_joawza_62 _withIcon_joawza_119 _withoutText_joawza_113"><svg viewBox="0 0 24 24" class="_icon_1lgbkjk_3 _dark_1lgbkjk_31 _sizeM_1lgbkjk_17 rs-text-3 rs-text-3_hardness_average rs-text-3_theme_dark _icon_joawza_525"><path d="M3.917 17.765a2.94 2.94 0 001.98.82c1.437.146 6.107.191 6.107.191s3.775-.006 6.289-.199a2.486 2.486 0 001.799-.812c.386-.568.63-1.22.714-1.901.112-1.03.172-2.065.18-3.101v-1.454a30.817 30.817 0 00-.18-3.1 4.32 4.32 0 00-.714-1.903 2.473 2.473 0 00-1.8-.81c-2.513-.195-6.284-.195-6.284-.195H12s-3.77 0-6.284.195a2.476 2.476 0 00-1.799.81 4.318 4.318 0 00-.714 1.903 30.782 30.782 0 00-.18 3.1v1.454c.008 1.036.068 2.07.18 3.1a4.31 4.31 0 00.714 1.902zM9.761 8.67l5.615 3.369-5.615 3.369V8.67z"></path></svg></a><a data-test="button" title="IntelliJ Platform Plugin SDK on LinkedIn" href="https://www.linkedin.com/showcase/jetbrains-marketplace" type="button" class="_main_joawza_17 _modeClear_joawza_434 _sizeS_joawza_92 _alignIconLeft_joawza_77 _dark_joawza_62 _withIcon_joawza_119 _withoutText_joawza_113"><svg viewBox="0 0 24 24" class="_icon_1lgbkjk_3 _dark_1lgbkjk_31 _sizeM_1lgbkjk_17 rs-text-3 rs-text-3_hardness_average rs-text-3_theme_dark _icon_joawza_525"><path d="M4.84 4h14.487a1.241 1.241 0 011.258 1.228v14.544A1.24 1.24 0 0119.327 21H4.84a1.24 1.24 0 01-1.255-1.228V5.228A1.238 1.238 0 014.84 4zm1.264 14.488h2.524v-8.113H6.104v8.113zM7.367 9.26a1.46 1.46 0 10-1.351-.898 1.442 1.442 0 001.351.898zm8.184 9.227h2.521v-4.449c0-2.19-.472-3.862-3.025-3.862a2.644 2.644 0 00-2.385 1.303h-.035v-1.105H10.21v8.113h2.518v-4.014c0-1.058.2-2.087 1.512-2.087 1.294 0 1.311 1.208 1.311 2.153v3.948z"></path></svg></a></div><ul class="footer__links" data-test="footer-links"><li class="footer__link"><a href="https://plugins.jetbrains.com/slack/" data-test="external-link " target="_blank" rel="noreferrer noopener" class="link link--dark rs-text-3 rs-text-3_hardness_hard rs-text-3_theme_dark">JetBrains Platform Slack</a></li><li class="footer__link"><a href="https://jb.gg/ipe" data-test="external-link " target="_blank" rel="noreferrer noopener" class="link link--dark rs-text-3 rs-text-3_hardness_hard rs-text-3_theme_dark">IntelliJ Platform Explorer</a></li><li class="footer__link"><a href="https://plugins.jetbrains.com/plugin-ideas/" data-test="external-link " target="_blank" rel="noreferrer noopener" class="link link--dark rs-text-3 rs-text-3_hardness_hard rs-text-3_theme_dark">Plugin Ideas</a></li></ul></div><p class="footer__powered rs-text-3 rs-text-3_theme_dark" data-test="powered-block">Powered by <a href="https://lp.jetbrains.com/writerside/" data-test="external-link powered-link" rel="" class="link link--dark"><span class="notranslate">JetBrains Writerside</span></a></p></div></footer></div></div></div></div></div><script type="text/javascript" id="" charset="">function checkCookieEnabled(){if(navigator.cookieEnabled)return!0;document.cookie="cookietest\x3d1";var b=document.cookie.indexOf("cookietest\x3d")!==-1;document.cookie="cookietest\x3d1; expires\x3dThu, 01-Jan-1970 00:00:01 GMT";return b}
(function(){var b="jb_cookies_consent_closed";if(checkCookieEnabled()&&document.cookie.indexOf(b)===-1&&document.cookie.indexOf("cookie_consent")===-1){var c="resources.jetbrains.com";location.hostname=="www.jetbrains.com.cn"&&(c="resources.jetbrains.com.cn");var d=location.search.indexOf("use-staging-cookie-banner")!==-1||location.hostname.indexOf("w3jbcom.aws.intellij.net")!==-1,a=document.createElement("link");a.setAttribute("rel","stylesheet");a.setAttribute("href",d?"https://resources-staging.w3jbcom-nonprod.aws.intellij.net/storage/ui/cookies-banner-4.css":
"https://"+c+"/storage/ui/cookies-banner-4.css");document.body.appendChild(a);a=document.createElement("script");a.setAttribute("src",d?"https://resources-staging.w3jbcom-nonprod.aws.intellij.net/storage/ui/cookies-banner-4.js":"https://"+c+"/storage/ui/cookies-banner-4.js");document.body.appendChild(a);var e={language:google_tag_manager["rm"]["58776"](43),cookieClosed:b,optOutLinkHref:location.hostname.endsWith(".jetbrains.com")?"https://www.jetbrains.com/opt-out/":"",options:{necessary:{isVisible:!0,isUncheckable:!1,
isChecked:!0},statistics:{isVisible:!0,isUncheckable:!0,isChecked:google_tag_manager["rm"]["58776"](44)=="US-CA"?!1:!0},marketing:{isVisible:!0,isUncheckable:!0,isChecked:!1},personalization:{isVisible:!0,isUncheckable:!0,isChecked:!1}},countryCodesWithoutPresetStatistics:"AT BE BG CH CY CZ DE DK EE ES FI FR GB GR HR HU IE IT LT LU LV MT NL PL PT RO SE SI SK NO IS LI".split(" "),actions:{close:{isVisible:!0}}};a.onload=function(){setTimeout(function(){new window.JetBrainsCookieGDPRBanner4(document.body,e)},50)}}})();</script><link rel="stylesheet" href="https://resources.jetbrains.com/storage/ui/cookies-banner-4.css"><script src="https://resources.jetbrains.com/storage/ui/cookies-banner-4.js"></script><script type="text/javascript" id="" charset="">setTimeout(function(){if(window.google_tag_manager&&window.location.search&&-1===window.location.href.indexOf("/shop/")&&-1===window.location.href.indexOf("/resellers/")){window.dataLayer=window.dataLayer||[];var a=/(&|\?)(_ga|_gac|_gl|fbclid|msclkid|twclid|mkt_tok|do_not_cache|gtm_[^&]*|utm_[^&]*)(=[^&|#]*)/g;window.location.search&&(a=window.location.search.replace(a,""),"\x26"===a[0]&&(a=a.replace("\x26","")),"?"===a[0]&&(a=a.replace("?","")),a=a?"?"+a:"",window.history.replaceState(null,null,
window.location.protocol+"//"+window.location.host+window.location.pathname+a+window.location.hash))}},4E3);</script><div data-nosnippet="" class="jetbrains-cookies-backdrop"></div><div data-nosnippet="" role="dialog" class="jetbrains-cookies-banner-4"><div class="jetbrains-cookies-banner-4__sign">Cookie Settings</div><div class="jetbrains-cookies-banner-4__body"><div class="jetbrains-cookies-banner-4__section"><p>Our website uses some cookies and records your IP address for the purposes of accessibility, security, and managing your access to the telecommunication network. You can disable data collection and cookies by changing your browser settings, but it may affect how this website functions. <a href="https://www.jetbrains.com/legal/docs/privacy/cookie-notice/">Learn more</a>.</p></div><div class="jetbrains-cookies-banner-4__section"><p class="jetbrains-cookies-banner-4__section__main-text">With your consent, JetBrains may also use cookies and your IP address to collect individual statistics and provide you with personalized offers and ads subject to the <a href="https://www.jetbrains.com/legal/docs/privacy/privacy/">Privacy Notice</a> and the <a href="https://www.jetbrains.com/legal/docs/company/useterms/">Terms of Use</a>. JetBrains may use <a href="https://www.jetbrains.com/legal/docs/privacy/third-parties/">third-party services</a> for this purpose. You can adjust or withdraw your consent at any time by visiting the <a href="https://www.jetbrains.com/opt-out/">Opt-Out page</a>.</p><!--if--><div class="jetbrains-cookies-banner-4__actions"><button class="jetbrains-cookies-banner-4-button jetbrains-cookies-banner-4-button--accent jetbrains-cookies-banner-4__action" data-jetbrains-cookies-banner-action="ACCEPT_ALL">Accept All</button><!--if--><button class="jetbrains-cookies-banner-4-button jetbrains-cookies-banner-4__action" data-jetbrains-cookies-banner-action="MANAGE_SETTINGS">Manage Settings</button><!--if--><!--if--><button class="jetbrains-cookies-banner-4-button jetbrains-cookies-banner-4__close" data-jetbrains-cookies-banner-action="CLOSE" aria-label="Close cookies banner">Close</button><!--if--></div></div></div></div><!--if--></body></html>