0Pricing
Java Academy · Lezione

Thread di piattaforma e virtual thread

Quando usare ciascun tipo

Thread di piattaforma e virtual thread è una lezione Java Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Java Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Java Academy include 4 lezioni in totale.

Due tipi di thread

Ora Java dispone di due tipi di thread. I thread di piattaforma sono i classici wrapper dei thread del sistema operativo. I thread virtuali sono leggeri e gestiti dalla JVM.

Capire quando utilizzare gli uni o gli altri è fondamentale per scrivere codice Java concorrente e scalabile.

Creazione di un thread di piattaforma

Create un thread di piattaforma con Thread.ofPlatform(), l'equivalente di Thread.ofVirtual().

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Thread p = Thread.ofPlatform().name("native-worker").start(() ->
            System.out.println("Platform? " + !Thread.currentThread().isVirtual()));
        p.join();
    }
}

Confronto dei costi

I thread di piattaforma sono pesanti:

  • Circa 1 MB di stack riservato per ciascuno
  • Lenti da creare
  • Limitati a poche migliaia

I thread virtuali sono economici: stack iniziale ridotto, creazione rapida e milioni di thread possibili.

Carichi di lavoro I/O-bound

Se il vostro task trascorre la maggior parte del tempo in attesa della rete, del disco o di un database, i thread virtuali offrono grandi vantaggi.

Quando un thread virtuale si blocca, il suo carrier viene liberato per eseguire altri thread; così un numero ridotto di thread del sistema operativo può gestire migliaia di richieste.

Carichi di lavoro CPU-bound

Per i calcoli puri che non si bloccano mai, i thread virtuali non offrono alcun aumento delle prestazioni. Siete limitati dal numero di core.

In questo caso lo strumento corretto è un pool fisso dimensionato in base ai processori.

import java.util.concurrent.*;

public class Main {
    public static void main(String[] args) throws Exception {
        int cores = Runtime.getRuntime().availableProcessors();
        try (ExecutorService cpu = Executors.newFixedThreadPool(cores)) {
            Future<Long> f = cpu.submit(() -> {
                long s = 0;
                for (long i = 0; i < 1_000_000L; i++) s += i;
                return s;
            });
            System.out.println("Cores: " + cores + ", sum: " + f.get());
        }
    }
}

Simulazione del blocco

Questo frammento mostra molti thread virtuali che dormono contemporaneamente, simulando operazioni di I/O bloccanti. Provate a immaginare 10.000 thread di piattaforma che fanno lo stesso.

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class Main {
    public static void main(String[] args) {
        AtomicInteger done = new AtomicInteger();
        try (ExecutorService exec = Executors.newVirtualThreadPerTaskExecutor()) {
            for (int i = 0; i < 10_000; i++) {
                exec.submit(() -> {
                    try { Thread.sleep(50); } catch (InterruptedException e) {}
                    done.incrementAndGet();
                });
            }
        }
        System.out.println("Finished blocking tasks: " + done.get());
    }
}

Stato daemon

I thread virtuali sono sempre thread daemon e non possono essere resi non-daemon. Per impostazione predefinita, i thread di piattaforma ereditano lo stato daemon del creatore, ma è possibile impostarlo esplicitamente.

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Thread v = Thread.ofVirtual().unstarted(() -> {});
        Thread p = Thread.ofPlatform().unstarted(() -> {});
        System.out.println("virtual daemon: " + v.isDaemon());
        System.out.println("platform daemon: " + p.isDaemon());
    }
}

Le priorità vengono ignorate

I thread virtuali restituiscono sempre una priorità pari a NORM_PRIORITY e l'impostazione della priorità non ha alcun effetto. La pianificazione è gestita dalla JVM, non dallo scheduler del sistema operativo.

public class Main {
    public static void main(String[] args) {
        Thread v = Thread.ofVirtual().unstarted(() -> {});
        v.setPriority(Thread.MAX_PRIORITY);
        System.out.println("Priority is still: " + v.getPriority());
    }
}

Linee guida per la scelta

Una regola pratica:

  • Molti task che attendono operazioni di I/O? Utilizzate i thread virtuali.
  • Calcoli intensivi limitati dalla CPU? Utilizzate un pool fisso di thread di piattaforma.
  • Avete bisogno di ottimizzare i thread a livello del sistema operativo, ad esempio priorità o affinità? Utilizzate i thread di piattaforma.

Possono coesistere

Non dovete scegliere un solo tipo per l'intero programma. Un'applicazione tipica usa thread virtuali per gestire le richieste e un piccolo pool di thread di piattaforma per le sezioni a uso intensivo della CPU.

Entrambi condividono la stessa API Thread, quindi combinarli è semplice.

Suggerimento per la migrazione

Quando migrate un servizio con un carico I/O elevato, la modifica più semplice consiste nel sostituire l'executor: rimpiazzate un pool fisso o con cache con newVirtualThreadPerTaskExecutor().

Prestate solo attenzione al pinning e all'uso eccessivo di ThreadLocal, argomenti trattati nella prossima lezione.

Verifica rapida

Scegliete il carico di lavoro in cui i thread virtuali offrono il vantaggio più evidente.

Riepilogo

Avete confrontato i due modelli di thread:

  • Thread di piattaforma: pesanti, basati sui thread del sistema operativo, ideali per carichi CPU-bound e per la configurazione a livello del sistema operativo
  • Thread virtuali: economici, gestiti dalla JVM, sempre daemon, ideali per la concorrenza I/O-bound
  • Possono coesistere e condividono la stessa API

Prossimo argomento: i problemi del pinning e dei ThreadLocal.

Domande Frequenti

La lezione «Thread di piattaforma e virtual thread» è gratuita?

Sì — il testo completo di «Thread di piattaforma e virtual thread» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Java Academy, passa a CoddyKit PRO. Il corso Java Academy include 4 lezioni in totale.

Cosa imparerò in «Thread di piattaforma e virtual thread»?

Quando usare ciascun tipo Eserciti Java Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Java Academy?

Non è richiesta alcuna esperienza precedente. Java Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.

Quanto tempo richiede la lezione «Thread di piattaforma e virtual thread»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Java Academy?

Sì. Ogni lezione Java Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Cosa sono i virtual thread
  2. Creare virtual thread
  3. Thread di piattaforma e virtual thread
  4. Problemi: pinning e ThreadLocal
← Torna a Java Academy