<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: b3o</title>
    <description>The latest articles on DEV Community by b3o (@b3o_b8o).</description>
    <link>https://dev.to/b3o_b8o</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4105183%2F241011ab-4883-48fb-b741-d0d766ccd9fc.png</url>
      <title>DEV Community: b3o</title>
      <link>https://dev.to/b3o_b8o</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/b3o_b8o"/>
    <language>en</language>
    <item>
      <title>Valhala: desmistificando uma das features mais aguardadas</title>
      <dc:creator>b3o</dc:creator>
      <pubDate>Wed, 02 Sep 2026 15:44:08 +0000</pubDate>
      <link>https://dev.to/b3o_b8o/valhala-desmistificando-uma-das-features-mais-aguardadas-do-java-26-323j</link>
      <guid>https://dev.to/b3o_b8o/valhala-desmistificando-uma-das-features-mais-aguardadas-do-java-26-323j</guid>
      <description>&lt;p&gt;Faz um tempo que eu fui fuçar no Project Valhalla e acabei ficando preso.&lt;/p&gt;

&lt;p&gt;A proposta parece simples: e se nem todo dado pequeno precisasse virar um objeto completo no heap, com identidade, header e referência?&lt;/p&gt;

&lt;p&gt;O projeto roda no OpenJDK desde 2014. Hoje ainda é experimental, mas já dá pra testar em builds early-access e acompanhar o que deve chegar nas próximas versões do Java. O ecossistema fala bastante do Java 26 em diante, e o Valhalla é um dos motivos.&lt;/p&gt;

&lt;h2&gt;
  
  
  O problema que demorei pra enxergar
&lt;/h2&gt;

&lt;p&gt;Java divide o mundo em dois: primitivos (&lt;code&gt;int&lt;/code&gt;, &lt;code&gt;long&lt;/code&gt;, &lt;code&gt;boolean&lt;/code&gt;...) e objetos (&lt;code&gt;Integer&lt;/code&gt;, &lt;code&gt;String&lt;/code&gt;, suas classes de domínio...).&lt;/p&gt;

&lt;p&gt;Primitivo guarda valor direto na memória. Objeto vive no heap, é acessado por referência e passa pelo GC.&lt;/p&gt;

&lt;p&gt;Isso funcionou por décadas. Só que no dia a dia a gente usa muita coisa pequena que na prática é só valor: coordenada, ID, intervalo de data, par de campos. Muitas vezes nem precisa de identidade. Só importa o conteúdo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Identidade vs valor
&lt;/h3&gt;

&lt;p&gt;Identidade é quando o objeto é único porque existe em um endereço próprio na memória:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"b3o"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"b3o"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;      &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;equals&lt;/code&gt; compara conteúdo. &lt;code&gt;==&lt;/code&gt; compara identidade.&lt;/p&gt;

&lt;p&gt;Pra muita regra de negócio, um ponto &lt;code&gt;(3, 4)&lt;/code&gt; é só &lt;code&gt;(3, 4)&lt;/code&gt;. Não importa "qual instância" é.&lt;/p&gt;

&lt;h2&gt;
  
  
  O custo invisível do modelo atual
&lt;/h2&gt;

&lt;p&gt;Olha uma classe simples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Coordenada&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na cabeça são 8 bytes. Na prática entram object header, alinhamento, padding e referência. Esse objeto pode facilmente ocupar 16 ou 24 bytes.&lt;/p&gt;

&lt;p&gt;Multiplica isso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Coordenada&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;coordenadas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Coordenada&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1_000_000&lt;/span&gt;&lt;span class="o"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Um milhão de objetos. Um milhão de alocações. Um milhão de headers. Cache locality vai embora, memória aumenta e o GC trabalha mais.&lt;/p&gt;

&lt;p&gt;Hoje o layout é mais ou menos assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ref] -&amp;gt; { x, y }
[ref] -&amp;gt; { x, y }
[ref] -&amp;gt; { x, y }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O Valhalla quer aproximar disso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[x][y][x][y][x][y]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dados contíguos, menos pointer chasing, menos cache miss. Parecido com struct em C ou value type em C#, mas sem abandonar GC e tipagem do Java.&lt;/p&gt;

&lt;h2&gt;
  
  
  Boxing e generics
&lt;/h2&gt;

&lt;p&gt;Outra dor clássica: generics não aceitam primitivo.&lt;/p&gt;

&lt;p&gt;Não existe &lt;code&gt;List&amp;lt;int&amp;gt;&lt;/code&gt;. Só &lt;code&gt;List&amp;lt;Integer&amp;gt;&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;numeros&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compila e roda. Só que cada &lt;code&gt;Integer&lt;/code&gt; é um objeto com header e identidade. Em coleção grande, o custo some no code review e aparece no profiler.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que o Valhalla quer resolver
&lt;/h2&gt;

&lt;p&gt;Em linhas gerais:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tipos sem identidade, comparados por valor&lt;/li&gt;
&lt;li&gt;armazenamento inline na memória (flattening)&lt;/li&gt;
&lt;li&gt;menos alocação desnecessária&lt;/li&gt;
&lt;li&gt;generics especializados sem boxing&lt;/li&gt;
&lt;li&gt;menos pressão no GC&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A pergunta que resume tudo: &lt;strong&gt;eu preciso saber qual instância é, ou só o valor importa?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Primitive classes na prática
&lt;/h2&gt;

&lt;p&gt;Na sintaxe experimental (em builds recentes também aparece como &lt;code&gt;value class&lt;/code&gt;), você declara tipos que se comportam como valor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;primitive&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sem identidade. Imutabilidade é favorecida. A JVM pode guardar os campos inline, sem criar um objeto separado no heap para cada instância.&lt;/p&gt;

&lt;h3&gt;
  
  
  Composição e campos nullable
&lt;/h3&gt;

&lt;p&gt;O interessante é que isso não fica limitado a tipos "planos". Dá pra compor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;primitive&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;primitive&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pessoa&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Point&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;childrenIds&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui entram detalhes importantes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;location&lt;/code&gt; é outro value type. Em cenários favoráveis, a JVM pode achatar (&lt;code&gt;flatten&lt;/code&gt;) os campos de &lt;code&gt;Point&lt;/code&gt; dentro de &lt;code&gt;Pessoa&lt;/code&gt;, em vez de ter referência para outro objeto.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;height&lt;/code&gt; é primitivo. Também pode ficar inline.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;childrenIds&lt;/code&gt; é array. Continua sendo referência, mas o array em si pode ser mais compacto dependendo do layout.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt; é &lt;code&gt;String&lt;/code&gt;, tipo de referência nullable. Campos nullable complicam flattening, porque &lt;code&gt;null&lt;/code&gt; quebra layout inline previsível.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ou seja: nem tudo vira bloco contínuo mágico. Tipos de referência e &lt;code&gt;null&lt;/code&gt; ainda têm custo. Mas o modelo já permite expressar melhor o que é "só dado" e o que precisa de identidade.&lt;/p&gt;

&lt;h3&gt;
  
  
  Arrays achatados
&lt;/h3&gt;

&lt;p&gt;Hoje, &lt;code&gt;Point[]&lt;/code&gt; seria um array de referências. Cada posição aponta para outro lugar na memória.&lt;/p&gt;

&lt;p&gt;Com Valhalla, um array de value type pode se comportar como bloco de valores:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[x][y][x][y][x][y]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso muda o perfil de memória em matrizes, simulações, processamento geométrico e qualquer fluxo com milhões de registros pequenos.&lt;/p&gt;

&lt;h2&gt;
  
  
  L-World, Q-types e L-types (visão geral)
&lt;/h2&gt;

&lt;p&gt;Sem entrar no nível de especificação da JVM, o modelo interno separa duas "projeções":&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Conceito&lt;/th&gt;
&lt;th&gt;Ideia&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Q-type&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Value type não-null, flattenable, sem identidade&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;L-type&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Referência tradicional, nullable, compatível com o Java de hoje&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Resumindo: &lt;strong&gt;Q&lt;/strong&gt; é valor puro inline. &lt;strong&gt;L&lt;/strong&gt; é o wrapper/referência que o código legado já conhece.&lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;L-World&lt;/strong&gt; é o esforço de unificar primitivos, objetos e value types sem quebrar bytecode e APIs antigas. A ideia não é substituir o Java atual. É fazer os dois mundos conviverem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Null-restricted types
&lt;/h2&gt;

&lt;p&gt;Outra peça do quebra-cabeça: deixar explícito se um tipo aceita &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Isso ajuda a JVM a otimizar flattening e melhora segurança. &lt;code&gt;null&lt;/code&gt; em campo inline é problema de layout e fonte de &lt;code&gt;NullPointerException&lt;/code&gt; escondido.&lt;/p&gt;

&lt;p&gt;No exemplo da &lt;code&gt;Pessoa&lt;/code&gt;, &lt;code&gt;String name&lt;/code&gt; aceita &lt;code&gt;null&lt;/code&gt;. Já &lt;code&gt;Point location&lt;/code&gt; em contextos null-restricted poderia ser tratado de forma mais agressiva pela JVM.&lt;/p&gt;

&lt;h2&gt;
  
  
  Specialized Generics
&lt;/h2&gt;

&lt;p&gt;Hoje, &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; com tipo primitivo ou value type costuma passar por boxing.&lt;/p&gt;

&lt;p&gt;Com generics especializados, a ideia é gerar layouts específicos em tempo de compilação. Algo como &lt;code&gt;List&amp;lt;Point&amp;gt;&lt;/code&gt; poderia armazenar valores inline, sem empilhar &lt;code&gt;Integer&lt;/code&gt;-like wrappers.&lt;/p&gt;

&lt;p&gt;Esse é um dos pontos com maior impacto prático, mas também um dos que mais demoram pra amadurecer no ecossistema inteiro (JDK, bibliotecas, frameworks).&lt;/p&gt;

&lt;h2&gt;
  
  
  Object header e Escape Analysis
&lt;/h2&gt;

&lt;p&gt;Objetos Java carregam header com metadados de runtime (marcas de GC, identidade, etc.). Value types querem reduzir ou eliminar esse custo quando identidade não importa.&lt;/p&gt;

&lt;p&gt;A JVM já faz &lt;strong&gt;Escape Analysis&lt;/strong&gt;: o JIT tenta perceber que um objeto não "escapou" do método e pode eliminar a alocação, usando registradores. O problema é que isso não é garantido. Depende do código, do compilador e do caminho de execução.&lt;/p&gt;

&lt;p&gt;O Valhalla quer tornar parte dessa otimização estrutural. Não depender só de "talvez o JIT resolva".&lt;/p&gt;

&lt;h2&gt;
  
  
  Impacto no GC
&lt;/h2&gt;

&lt;p&gt;Menos objetos na heap significa:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;menos tracing&lt;/li&gt;
&lt;li&gt;menos scanning&lt;/li&gt;
&lt;li&gt;menos compactação&lt;/li&gt;
&lt;li&gt;menos pausas&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GC moderno sofre com bilhões de micro-objetos. Valhalla ataca exatamente o padrão que a gente cria sem perceber em código "simples".&lt;/p&gt;

&lt;h2&gt;
  
  
  Onde estamos hoje
&lt;/h2&gt;

&lt;p&gt;Ainda é experimental. Build separada, APIs em evolução, sintaxe em preview.&lt;/p&gt;

&lt;p&gt;Nas builds mais recentes, a direção do OpenJDK aponta para &lt;strong&gt;value classes&lt;/strong&gt; (JEP 401) como feature preview nas próximas versões da plataforma. A sintaxe &lt;code&gt;primitive class&lt;/code&gt; que aparece em materiais e early-access pode variar conforme a build. Vale sempre olhar a documentação da build que você baixou.&lt;/p&gt;

&lt;p&gt;Não é algo pra colocar em produção amanhã. Mas o problema que resolve é real e antigo.&lt;/p&gt;

&lt;p&gt;Java ganhou o mundo pela produtividade. O Valhalla pergunta se dá pra manter isso sem pagar caro em todo valor pequeno.&lt;/p&gt;

&lt;p&gt;Build pra testar:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://jdk.java.net/valhalla/" rel="noopener noreferrer"&gt;https://jdk.java.net/valhalla/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se você mexe com Java e já olhou pro profiler pensando "por que isso alocou tanto?", vale acompanhar. Não precisa virar especialista em JVM. Só entender o rumo já muda como você enxerga modelagem de dados no código.&lt;/p&gt;

</description>
      <category>valhalla</category>
      <category>java</category>
      <category>jdk</category>
    </item>
    <item>
      <title>Threads e Virtual Threads Guia ilustrado</title>
      <dc:creator>b3o</dc:creator>
      <pubDate>Wed, 02 Sep 2026 00:08:14 +0000</pubDate>
      <link>https://dev.to/b3o_b8o/threads-e-virtual-threads-guia-ilustrado-1b64</link>
      <guid>https://dev.to/b3o_b8o/threads-e-virtual-threads-guia-ilustrado-1b64</guid>
      <description>&lt;h1&gt;
  
  
  Threads e Virtual Threads: entendendo de uma forma simples
&lt;/h1&gt;

&lt;p&gt;Threads e Virtual Threads são assuntos que, à primeira vista, podem parecer complexos e desafiadores durante a carreira no desenvolvimento de software.&lt;/p&gt;

&lt;p&gt;Muitas vezes, esses conceitos acabam sendo deixados de lado porque simplesmente "funcionam no background". Criamos uma aplicação, fazemos algumas requisições e, na maioria das vezes, não precisamos pensar muito sobre quem está executando aquilo por trás.&lt;/p&gt;

&lt;p&gt;Porém, quando começamos a estudar mais sobre como nossas aplicações funcionam, alguns termos começam a aparecer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Concorrência&lt;/li&gt;
&lt;li&gt;Paralelismo&lt;/li&gt;
&lt;li&gt;Escalonamento&lt;/li&gt;
&lt;li&gt;Gerenciamento de recursos&lt;/li&gt;
&lt;li&gt;Threads&lt;/li&gt;
&lt;li&gt;Virtual Threads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E é aí que o assunto começa a parecer um pouco mais complicado.&lt;/p&gt;

&lt;p&gt;Por isso decidi escrever este artigo de uma forma um pouco diferente. Além de compartilhar conhecimento, este material também é uma forma de consolidar e fixar aquilo que venho aprendendo.&lt;/p&gt;

&lt;p&gt;Acredito muito na ideia de que, quando conseguimos explicar algo de maneira simples, é porque começamos a entender o assunto de verdade.&lt;/p&gt;

&lt;p&gt;A ideia aqui não é criar um conteúdo extremamente aprofundado ou entrar em todos os detalhes internos da JVM. O objetivo é revisitar os conceitos fundamentais e, principalmente, tentar explicar tudo de uma forma simples e visual.&lt;/p&gt;

&lt;p&gt;Ao final, a ideia é que você não apenas saiba responder o que é uma Thread ou uma Virtual Thread, mas consiga visualizar mentalmente o que está acontecendo por trás do código.&lt;/p&gt;




&lt;h1&gt;
  
  
  Threads
&lt;/h1&gt;

&lt;p&gt;Para começarmos essa jornada, gosto bastante de utilizar uma analogia.&lt;/p&gt;

&lt;p&gt;Imagine que estamos em um restaurante.&lt;/p&gt;

&lt;p&gt;Chegam cinco pedidos na cozinha:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pedido 1
Pedido 2
Pedido 3
Pedido 4
Pedido 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mas temos apenas três funcionários:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;João
Maria
Pedro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cada funcionário começa a trabalhar em um pedido:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;João  -&amp;gt; Pedido 1
Maria -&amp;gt; Pedido 2
Pedro -&amp;gt; Pedido 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Os outros dois pedidos precisam esperar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1wyt9ekjz2m2a3l3iy18.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1wyt9ekjz2m2a3l3iy18.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quando João termina seu pedido, por exemplo, ele pode pegar o próximo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;João termina o Pedido 1
          |
          v
João começa o Pedido 4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos utilizar essa ideia para começar a entender o conceito de Thread.&lt;/p&gt;

&lt;p&gt;De forma bastante simplificada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pedido
   |
   v
Thread
   |
   v
Execução
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O pedido representa uma tarefa que precisa ser realizada, enquanto a Thread representa uma unidade de execução responsável por realizar esse trabalho.&lt;/p&gt;

&lt;p&gt;Essa analogia não representa todos os detalhes técnicos de uma Thread, mas é uma boa forma de começar a construir uma imagem mental sobre o assunto.&lt;/p&gt;

&lt;h1&gt;
  
  
  O problema começa quando temos muitas tarefas
&lt;/h1&gt;

&lt;p&gt;Até aqui tudo parece simples.&lt;/p&gt;

&lt;p&gt;Temos algumas tarefas e alguns funcionários.&lt;/p&gt;

&lt;p&gt;Agora imagine que nosso restaurante recebeu 10.000 pedidos.&lt;/p&gt;

&lt;p&gt;Seguindo a mesma lógica, poderíamos pensar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10.000 tarefas
      |
      v
10.000 Threads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E aqui começamos a encontrar um problema.&lt;/p&gt;

&lt;p&gt;Threads tradicionais possuem um custo.&lt;/p&gt;

&lt;p&gt;Criar e manter milhares de Threads significa utilizar memória e outros recursos do sistema operacional. Além disso, essas Threads precisam ser gerenciadas e escalonadas.&lt;/p&gt;

&lt;p&gt;E existe outro detalhe importante.&lt;/p&gt;

&lt;p&gt;Nem todas essas Threads estão realmente executando alguma coisa.&lt;/p&gt;

&lt;p&gt;Imagine uma requisição que precisa consultar um banco de dados:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Requisição
    |
    v
Banco de dados
    |
    v
Esperando resposta...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Durante esse período, a aplicação está esperando uma resposta externa.&lt;/p&gt;

&lt;p&gt;Esse tipo de operação é conhecido como I/O, ou Input/Output.&lt;/p&gt;

&lt;p&gt;E esse cenário é extremamente comum em aplicações backend.&lt;/p&gt;

&lt;p&gt;Uma requisição pode passar boa parte do seu tempo esperando:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Banco de dados&lt;/li&gt;
&lt;li&gt;APIs externas&lt;/li&gt;
&lt;li&gt;Arquivos&lt;/li&gt;
&lt;li&gt;Rede&lt;/li&gt;
&lt;li&gt;Outros serviços&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ou seja, podemos ter milhares de Threads existentes, mas muitas delas podem estar simplesmente esperando alguma operação terminar.&lt;/p&gt;

&lt;h1&gt;
  
  
  O que existe dentro de uma Thread?
&lt;/h1&gt;

&lt;p&gt;Para entender por que uma Thread possui um custo, precisamos olhar um pouco para o que ela precisa manter durante sua execução.&lt;/p&gt;

&lt;p&gt;Imagine este código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;processarPedido&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pedido&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;buscarPedido&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pagamento&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;processarPagamento&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pedido&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;salvar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pagamento&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enquanto esse código está sendo executado, precisamos manter informações sobre o estado daquela execução.&lt;/p&gt;

&lt;p&gt;Podemos imaginar conceitualmente algo assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Thread

├── Estado da execução
├── Stack
├── Variáveis locais
├── Chamadas de métodos
└── Informações necessárias para continuar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Um dos elementos mais importantes para entendermos aqui é a Stack.&lt;/p&gt;

&lt;h1&gt;
  
  
  Entendendo a Stack
&lt;/h1&gt;

&lt;p&gt;Imagine que temos as seguintes chamadas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;processarPedido()
       |
       v
buscarPedido()
       |
       v
consultarBanco()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enquanto &lt;code&gt;consultarBanco()&lt;/code&gt; está sendo executado, precisamos manter o contexto das chamadas anteriores.&lt;/p&gt;

&lt;p&gt;Podemos visualizar isso como uma pilha:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+----------------------+
| consultarBanco()     |
+----------------------+
| buscarPedido()       |
+----------------------+
| processarPedido()    |
+----------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quando &lt;code&gt;consultarBanco()&lt;/code&gt; termina, ela sai da Stack.&lt;/p&gt;

&lt;p&gt;Depois &lt;code&gt;buscarPedido()&lt;/code&gt; termina.&lt;/p&gt;

&lt;p&gt;E finalmente &lt;code&gt;processarPedido()&lt;/code&gt; termina.&lt;/p&gt;

&lt;p&gt;A Stack é apenas uma parte do que uma Thread precisa manter, mas ela já ajuda a entender que uma Thread não é simplesmente uma abstração sem custo.&lt;/p&gt;

&lt;p&gt;Podemos pensar, de forma simplificada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 Thread
    |
    v
1 contexto de execução

10 Threads
    |
    v
10 contextos de execução

1.000 Threads
    |
    v
1.000 contextos de execução
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Não significa que o consumo de memória seja simplesmente proporcional dessa forma ou que o único custo de uma Thread seja sua Stack. A ideia aqui é apenas entender que manter uma grande quantidade de Threads tradicionais possui um custo.&lt;/p&gt;

&lt;h1&gt;
  
  
  E não é apenas memória
&lt;/h1&gt;

&lt;p&gt;Talvez você esteja pensando:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Então o problema é apenas a memória?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Não.&lt;/p&gt;

&lt;p&gt;Existe também o gerenciamento dessas Threads.&lt;/p&gt;

&lt;p&gt;Imagine que temos 10.000 Threads, mas nossa máquina possui apenas alguns núcleos de CPU.&lt;/p&gt;

&lt;p&gt;Todas essas Threads não podem executar fisicamente ao mesmo tempo.&lt;/p&gt;

&lt;p&gt;O sistema operacional precisa decidir quais Threads vão executar e quando.&lt;/p&gt;

&lt;p&gt;De forma simplificada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Thread A -&amp;gt; executando
Thread B -&amp;gt; esperando
Thread C -&amp;gt; executando
Thread D -&amp;gt; esperando
Thread E -&amp;gt; esperando
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse processo envolve escalonamento e, quando necessário, troca de contexto entre diferentes Threads.&lt;/p&gt;

&lt;p&gt;Esse é um assunto que merece uma explicação própria, então não vou entrar em detalhes aqui.&lt;/p&gt;

&lt;p&gt;Por enquanto, basta guardar a seguinte ideia:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Threads tradicionais possuem custos de memória, criação, gerenciamento e escalonamento.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;E é justamente nesse ponto que as Virtual Threads começam a fazer sentido.&lt;/p&gt;

&lt;h1&gt;
  
  
  Virtual Threads
&lt;/h1&gt;

&lt;p&gt;As Virtual Threads surgiram no Java com o objetivo de tornar muito mais leve a criação e o gerenciamento de grandes quantidades de tarefas concorrentes.&lt;/p&gt;

&lt;p&gt;Em vez de imaginar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 tarefa
   |
   v
1 Thread do sistema operacional
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;podemos começar a imaginar algo diferente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Muitas tarefas

Thread  Thread  Thread  Thread  Thread
Thread  Thread  Thread  Thread  Thread
Thread  Thread  Thread  Thread  Thread
             |
             v
       Poucas Threads
       do sistema operacional
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No modelo de Virtual Threads, temos as Virtual Threads sendo executadas sobre Threads do sistema operacional, chamadas de Carrier Threads. (As carrier threads são como os caixas do supermercado, que atendem e processam os clientes (threads virtuais) à medida que eles chegam para pagar.).&lt;/p&gt;

&lt;p&gt;Podemos visualizar assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Virtual Threads

  Thread  Thread  Thread  Thread
  Thread  Thread  Thread  Thread
  Thread  Thread  Thread  Thread
              |
              v
       Carrier Threads

          Thread Thread Thread
              |
              v
             CPU
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A JVM é responsável por gerenciar esse relacionamento.&lt;/p&gt;

&lt;h1&gt;
  
  
  O que acontece quando uma Virtual Thread precisa esperar?
&lt;/h1&gt;

&lt;p&gt;Agora chegamos em uma das partes mais interessantes.&lt;/p&gt;

&lt;p&gt;Imagine que uma Virtual Thread esteja executando uma operação que precisa esperar uma resposta do banco:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Virtual Thread
       |
       v
Consulta ao banco
       |
       v
   esperando...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em operações bloqueantes suportadas pelo modelo de Virtual Threads, a JVM pode retirar essa Virtual Thread da Carrier Thread enquanto ela está aguardando.&lt;/p&gt;

&lt;p&gt;Isso permite que a Carrier Thread seja utilizada para executar outra Virtual Thread.&lt;/p&gt;

&lt;p&gt;Podemos imaginar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Antes:

Virtual Thread A
       |
       v
Carrier Thread
       |
       v
      CPU
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A Virtual Thread A precisa esperar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Virtual Thread A
       |
       v
   esperando
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A Carrier Thread pode então executar outra Virtual Thread:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Virtual Thread B
       |
       v
Carrier Thread
       |
       v
      CPU
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quando a operação da Virtual Thread A estiver pronta para continuar, ela poderá voltar a ser executada.&lt;/p&gt;

&lt;p&gt;Essa é uma das ideias fundamentais por trás das Virtual Threads.&lt;/p&gt;

&lt;h1&gt;
  
  
  Thread tradicional vs Virtual Thread
&lt;/h1&gt;

&lt;p&gt;Agora podemos visualizar melhor a diferença.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thread tradicional
&lt;/h2&gt;

&lt;p&gt;De forma simplificada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tarefa
  |
  v
Thread
  |
  v
CPU
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Existe uma relação mais direta entre a unidade de execução e a Thread do sistema operacional.&lt;/p&gt;

&lt;h2&gt;
  
  
  Virtual Thread
&lt;/h2&gt;

&lt;p&gt;Agora temos uma camada adicional:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tarefa
  |
  v
Virtual Thread
  |
  v
Carrier Thread
  |
  v
CPU
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso permite trabalhar com uma quantidade muito maior de unidades de execução leves sem precisar criar uma Thread do sistema operacional para cada uma delas.&lt;/p&gt;

&lt;h1&gt;
  
  
  Virtual Thread não é uma Thread mais rápida
&lt;/h1&gt;

&lt;p&gt;Essa é uma confusão bastante comum.&lt;/p&gt;

&lt;p&gt;Quando ouvimos que Virtual Threads são "leves", podemos acabar pensando:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Então elas são simplesmente Threads tradicionais mais rápidas."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Não é exatamente isso.&lt;/p&gt;

&lt;p&gt;Virtual Threads não criam mais CPU.&lt;/p&gt;

&lt;p&gt;Elas também não fazem uma operação que demora 10 segundos terminar em 1 segundo.&lt;/p&gt;

&lt;p&gt;O principal benefício está na capacidade de lidar com &lt;strong&gt;grandes quantidades de tarefas concorrentes&lt;/strong&gt;, principalmente quando essas tarefas passam bastante tempo esperando operações de I/O.&lt;/p&gt;

&lt;p&gt;Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Requisição
    |
    v
Banco de dados
    |
    v
Esperando...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enquanto uma tarefa está esperando, a capacidade de execução disponível pode ser utilizada para trabalhar em outra tarefa.&lt;/p&gt;

&lt;p&gt;É nesse tipo de cenário que Virtual Threads se tornam especialmente interessantes.&lt;/p&gt;

&lt;h1&gt;
  
  
  Voltando para a nossa cozinha
&lt;/h1&gt;

&lt;p&gt;Vamos voltar para o restaurante.&lt;/p&gt;

&lt;p&gt;Antes tínhamos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pedidos:

Pedido 1
Pedido 2
Pedido 3
Pedido 4
Pedido 5

Funcionários:

João
Maria
Pedro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se os três funcionários estivessem ocupados, os outros pedidos precisariam esperar.&lt;/p&gt;

&lt;p&gt;Agora imagine que conseguimos representar cada pedido com uma unidade de execução muito mais leve:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pedido 1 -&amp;gt; Virtual Thread
Pedido 2 -&amp;gt; Virtual Thread
Pedido 3 -&amp;gt; Virtual Thread
Pedido 4 -&amp;gt; Virtual Thread
Pedido 5 -&amp;gt; Virtual Thread
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E temos alguns funcionários físicos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Carrier Thread 1
Carrier Thread 2
Carrier Thread 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se uma tarefa precisar esperar alguma coisa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pedido 1
   |
   v
Esperando banco
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;o funcionário não precisa necessariamente ficar parado esperando aquele pedido.&lt;/p&gt;

&lt;p&gt;Ele pode trabalhar em outro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pedido 2
   |
   v
Carrier Thread
   |
   v
Execução
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa é a imagem mental que eu gostaria que você levasse deste artigo.&lt;/p&gt;

&lt;h1&gt;
  
  
  A ideia principal
&lt;/h1&gt;

&lt;p&gt;Se você lembrar apenas de uma coisa deste artigo, lembre-se disso.&lt;/p&gt;

&lt;p&gt;Uma Thread tradicional pode ser representada de forma simplificada assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tarefa
  |
  v
Thread do sistema operacional
  |
  v
CPU
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Já com Virtual Threads temos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tarefa
  |
  v
Virtual Thread
  |
  v
Carrier Thread
  |
  v
CPU
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A grande ideia não é simplesmente ter uma Thread mais rápida.&lt;/p&gt;

&lt;p&gt;É poder trabalhar com &lt;strong&gt;muitas unidades leves de execução&lt;/strong&gt;, permitindo que a JVM gerencie melhor a utilização das Threads do sistema operacional.&lt;/p&gt;

&lt;p&gt;Isso é especialmente interessante em aplicações que lidam com muitas operações de I/O.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusão
&lt;/h1&gt;

&lt;p&gt;Threads são fundamentais para entender como nossas aplicações executam tarefas de forma concorrente.&lt;/p&gt;

&lt;p&gt;Porém, quando começamos a trabalhar com milhares de tarefas simultâneas, o custo de criar e gerenciar milhares de Threads tradicionais pode se tornar um problema.&lt;/p&gt;

&lt;p&gt;As Virtual Threads apresentam uma abordagem diferente.&lt;/p&gt;

&lt;p&gt;Elas permitem representar muitas tarefas concorrentes de maneira muito mais leve e deixam a JVM cuidar do gerenciamento dessas execuções sobre as Carrier Threads.&lt;/p&gt;

&lt;p&gt;E talvez a melhor forma de guardar tudo isso seja voltando para a nossa cozinha.&lt;/p&gt;

&lt;p&gt;Não estamos criando milhares de funcionários.&lt;/p&gt;

&lt;p&gt;Estamos criando uma forma melhor de organizar os pedidos para que os funcionários disponíveis não fiquem parados enquanto um pedido está esperando alguma coisa.&lt;/p&gt;

&lt;p&gt;Essa é a ideia central das Virtual Threads.&lt;/p&gt;

&lt;p&gt;Nos próximos artigos, podemos sair da analogia e começar a olhar para o Java de verdade: como criar uma Virtual Thread, como funciona o &lt;code&gt;Executors.newVirtualThreadPerTaskExecutor()&lt;/code&gt;, o que acontece com a Stack e como a JVM gerencia as Carrier Threads.&lt;/p&gt;

</description>
      <category>threads</category>
      <category>e</category>
      <category>virtualthreads</category>
    </item>
  </channel>
</rss>
