Breve introduzione a Java Thread.yield ()

1. Panoramica

In questo tutorial, esploreremo il metodo yield () nella classe Thread .

Lo confronteremo con altri idiomi di concorrenza disponibili in Java e alla fine ne esploreremo le applicazioni pratiche.

2. Sinossi di yield ()

Come suggerisce la documentazione ufficiale, yield () fornisce un meccanismo per informare lo "scheduler" che il thread corrente è disposto a rinunciare al suo uso corrente del processore ma vorrebbe essere pianificato di nuovo il prima possibile.

Lo “scheduler” è libero di aderire o ignorare queste informazioni e infatti, ha un comportamento variabile a seconda del sistema operativo.

Il frammento di codice seguente visualizza due thread con la stessa priorità che si producono dopo ogni pianificazione:

public class ThreadYield { public static void main(String[] args) { Runnable r = () -> { int counter = 0; while (counter < 2) { System.out.println(Thread.currentThread() .getName()); counter++; Thread.yield(); } }; new Thread(r).start(); new Thread(r).start(); } }

Quando proviamo a eseguire il programma sopra più volte, otteniamo risultati diversi; alcuni di loro sono menzionati di seguito:

Esegui 1:

Thread-0 Thread-1 Thread-1 Thread-0

Esegui 2:

Thread-0 Thread-0 Thread-1 Thread-1

Quindi, come puoi vedere, il comportamento di yield () è non deterministico e anche dipendente dalla piattaforma.

3. Confronto con altri modi di dire

Esistono altri costrutti per influenzare la progressione relativa dei thread. Includono wait () , notify () e notifyAll () come parte della classe Object , join () come parte della classe Thread e sleep () come parte della classe Thread .

Vediamo come si confrontano con yield () .

3.1. yield () vs wait ()

  • Mentre yield () viene invocato nel contesto del thread corrente, wait () può essere invocato solo su un lock acquisito esplicitamente all'interno di un blocco o metodo sincronizzato
  • A differenza di yield () , è possibile che wait () specifichi un periodo di tempo minimo da attendere prima di qualsiasi tentativo di pianificare di nuovo il thread
  • Con wait () è anche possibile riattivare il thread in qualsiasi momento tramite una chiamata di notify () o notifyAll () sull'oggetto lock interessato

3.2. yield () vs sleep ()

  • Mentre yield () può solo fare un tentativo euristico di sospendere l'esecuzione del thread corrente senza alcuna garanzia di quando sarà programmato di nuovo, sleep () può forzare lo scheduler a sospendere l'esecuzione del thread corrente almeno per il tempo indicato periodo come parametro.

3.3. yield () vs join ()

  • Il thread corrente può invocare join () su qualsiasi altro thread che fa aspettare il thread corrente che l'altro thread muoia prima di procedere
  • Facoltativamente può menzionare un periodo di tempo come parametro che indica il tempo massimo per il quale il thread corrente deve attendere prima di riprendere

4. Utilizzo di yield ()

Come suggerisce la documentazione ufficiale, è raramente necessario usare yield () e quindi dovrebbe essere evitato a meno che non sia molto chiaro con gli obiettivi alla luce del suo comportamento.

Tuttavia, alcuni degli usi per yield () includono la progettazione di costrutti di controllo della concorrenza, il miglioramento della reattività del sistema in un programma pesante, ecc.

Tuttavia, questi utilizzi devono essere accompagnati da profiling e benchmarking dettagliati per garantire il risultato desiderato.

5. conclusione

In questo breve articolo, abbiamo discusso il metodo yield () nella classe Thread e ne abbiamo visto il comportamento e i limiti attraverso un frammento di codice.

Abbiamo anche esplorato il suo confronto con altri idiomi di concorrenza disponibili in Java e infine abbiamo esaminato alcuni dei casi d'uso in cui yield () potrebbe essere utile.

Come sempre, puoi controllare gli esempi forniti in questo articolo su GitHub.