Ingresso multithread Java
Ogni applicazione può avere più processi (istanze). Ognuno di questi processi può essere assegnato come thread singolo o thread multipli. In questo tutorial vedremo come eseguire più attività contemporaneamente e impareremo anche di più sui thread e sulla sincronizzazione tra thread.
Cos'è il thread singolo?
Un unico thread in entrata Java è fondamentalmente un'unità di elaborazione leggera e più piccola. Java utilizza i thread utilizzando una "classe thread". Esistono due tipi di thread: thread utente e thread demone (i thread daemon vengono utilizzati quando vogliamo pulire l'applicazione e vengono utilizzati in background). Quando un'applicazione inizia per la prima volta, viene creato un thread utente. Dopo di che, possiamo creare molti thread utente e thread daemon.
Esempio di thread singolo:
package demotest; public class GuruThread { public static void main(String[] args) { System.out.println("Single Thread"); } }
Vantaggi del filo singolo:
- Riduce il sovraccarico nell'applicazione poiché viene eseguito un singolo thread nel sistema
- Inoltre, riduce i costi di manutenzione dell'applicazione.
In cosa consiste il multithreading Java?
multithreading in Java è un processo di esecuzione di due o più thread contemporaneamente per sfruttare al massimo la CPU. Le applicazioni multithread eseguono due o più thread contemporaneamente. Quindi, è anche noto come Concorrenza in Java. Ogni filo corre parallelo all'altro. Più thread non allocano aree di memoria separate, quindi risparmiano memoria. Inoltre, il cambio di contesto tra i thread richiede meno tempo.
Esempio di multi thread:
package demotest; public class GuruThread1 implements Runnable { public static void main(String[] args) { Thread guruThread1 = new Thread("Guru1"); Thread guruThread2 = new Thread("Guru2"); guruThread1.start(); guruThread2.start(); System.out.println("Thread names are following:"); System.out.println(guruThread1.getName()); System.out.println(guruThread2.getName()); } @Override public void run() { } }
Vantaggi del multithread:
- Gli utenti non vengono bloccati perché i thread sono indipendenti e possiamo eseguire più operazioni alla volta
- Pertanto i thread sono indipendenti, gli altri thread non verranno influenzati se un thread soddisfa un'eccezione.
Discussione sul ciclo di vita Java
Il ciclo di vita di un thread:
Esistono varie fasi del ciclo di vita del filo, come mostrato nel diagramma sopra:
- Nuovo
- eseguibile
- corsa
- In attesa
- Morto
- Novità: In questa fase viene creato il thread utilizzando la classe “Classe thread”. Rimane in questo stato fino al programma inizio il filo. È noto anche come filo nato.
- Eseguibile: In questa pagina l'istanza del thread viene invocata con un metodo start. Il controllo del thread viene assegnato allo scheduler per completare l'esecuzione. Dipende dallo scheduler, se eseguire il thread.
- Esecuzione: Quando il thread inizia l'esecuzione, lo stato viene modificato in stato "in esecuzione". Lo scheduler seleziona un thread dal pool di thread e inizia l'esecuzione nell'applicazione.
- In attesa: Questo è lo stato in cui un thread deve attendere. Poiché nell'applicazione sono in esecuzione più thread, è necessaria la sincronizzazione tra i thread. Quindi, un thread deve attendere finché l'altro thread non viene eseguito. Pertanto, questo stato è definito stato di attesa.
- Morto: Questo è lo stato in cui il thread viene terminato. Il thread è in stato di esecuzione e non appena ha completato l'elaborazione è in "stato morto".
Metodi di multithreading in Java
Alcuni dei metodi comunemente usati per i thread sono:Metodo | Descrizione |
---|---|
inizio() | Questo metodo avvia l'esecuzione del thread e JVM chiama il metodo run() sul thread. |
Sospensione (int millisecondi) | Questo metodo fa sì che il thread vada in sleep, quindi l'esecuzione del thread si fermerà per i millisecondi forniti e dopodiché il thread ricomincerà a essere eseguito. Questo aiuta nella sincronizzazione dei thread. |
getName () | Restituisce il nome del thread. |
setPriority(int nuovapriorità) | Cambia la priorità del thread. |
prodotto () | Causa l'esecuzione del thread corrente in caso di arresto e degli altri thread. |
Esempio: In questo programma multithread in Java Ad esempio, creeremo un thread ed esploreremo i metodi integrati disponibili per i thread.
package demotest; public class thread_example1 implements Runnable { @Override public void run() { } public static void main(String[] args) { Thread guruthread1 = new Thread(); guruthread1.start(); try { guruthread1.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } guruthread1.setPriority(1); int gurupriority = guruthread1.getPriority(); System.out.println(gurupriority); System.out.println("Thread Running"); } }
Spiegazione del codice:
- Riga di codice 2: Stiamo creando una classe "thread_Example1" che implementa l'interfaccia Runnable (dovrebbe essere implementata da qualsiasi classe le cui istanze devono essere eseguite dal thread).
- Riga di codice 4: Sostituisce il metodo run dell'interfaccia eseguibile poiché è obbligatorio sovrascrivere quel metodo
- Riga di codice 6: Qui abbiamo definito il metodo principale con cui inizieremo l'esecuzione del thread.
- Riga di codice 7: Qui stiamo creando un nuovo nome di thread come "guruthread1" istanziando una nuova classe di thread.
- Riga di codice 8: utilizzeremo il metodo "start" del thread utilizzando l'istanza "guruthread1". Qui il thread inizierà l'esecuzione.
- Riga di codice 10: Qui stiamo utilizzando il metodo "sleep" del thread utilizzando l'istanza "guruthread1". Pertanto, il thread resterà inattivo per 1000 millisecondi.
- Codice 9-14: Qui abbiamo inserito il metodo sleep nel blocco try catch poiché si verifica un'eccezione verificata, ad esempio un'eccezione interrotta.
- Riga di codice 15: Qui stiamo impostando la priorità del thread su 1 a seconda di quale priorità fosse
- Riga di codice 16: Qui stiamo ottenendo la priorità del thread usando getPriority()
- Riga di codice 17: Qui stiamo stampando il valore recuperato da getPriority
- Riga di codice 18: Qui stiamo scrivendo un testo che il thread è in esecuzione.
Quando esegui il codice sopra, ottieni il seguente output:
Produzione:
5 è la priorità del thread e Thread Running è il testo che è l'output del nostro codice.
Java Filo Synccronizzazione
Nel multithreading, c'è il comportamento asincrono dei programmi. Se un thread sta scrivendo alcuni dati e un altro thread sta leggendo dati contemporaneamente, potrebbe creare incoerenza nell'applicazione. Quando c'è la necessità di accedere alle risorse condivise da due o più thread, allora viene utilizzato l'approccio di sincronizzazione. Java ha fornito metodi sincronizzati per implementare un comportamento sincronizzato.
In questo approccio, una volta che il thread raggiunge l'interno del blocco sincronizzato, nessun altro thread può chiamare quel metodo sullo stesso oggetto. Tutti i thread devono attendere che quel thread finisca il blocco sincronizzato e ne esca. In questo modo, la sincronizzazione aiuta in un'applicazione multithread. Un thread deve attendere che un altro thread finisca la sua esecuzione, solo allora gli altri thread possono essere eseguiti.
Può essere scritto nella seguente forma:
Synchronized(object) { //Block of statements to be synchronized }
Ingresso multithread Java Programmi di esempio
In questo multithreading Java Ad esempio, prenderemo due thread e recupereremo i nomi del thread.
Example1:
GuruThread1.java package demotest; public class GuruThread1 implements Runnable{ /** * @param args */ public static void main(String[] args) { Thread guruThread1 = new Thread("Guru1"); Thread guruThread2 = new Thread("Guru2"); guruThread1.start(); guruThread2.start(); System.out.println("Thread names are following:"); System.out.println(guruThread1.getName()); System.out.println(guruThread2.getName()); } @Override public void run() { } }
Spiegazione del codice:
- Riga di codice 3: Abbiamo preso una classe "GuruThread1" che implementa Runnable (dovrebbe essere implementata da qualsiasi classe le cui istanze devono essere eseguite dal thread).
- Riga di codice 8: Questo è il metodo principale della classe
- Riga di codice 9: Qui stiamo istanziando la classe Thread e creando un'istanza denominata "guruThread1" e creando un thread.
- Riga di codice 10: Qui stiamo istanziando la classe Thread e creando un'istanza denominata "guruThread2" e creando un thread.
- Riga di codice 11: Stiamo iniziando il thread, ad esempio guruThread1.
- Riga di codice 12: Stiamo iniziando il thread, ad esempio guruThread2.
- Riga di codice 13: Emettendo il testo come "I nomi dei thread sono i seguenti:"
- Riga di codice 14: Ottenere il nome del thread 1 utilizzando il metodo getName() della classe thread.
- Riga di codice 15: Ottenere il nome del thread 2 utilizzando il metodo getName() della classe thread.
Quando esegui il codice sopra, ottieni il seguente output:
Produzione:
I nomi dei thread vengono visualizzati qui come
- Guru1
- Guru2
Esempio 2:
In questo multithreading in Java Ad esempio, impareremo come sovrascrivere i metodi run() e start() di un'interfaccia eseguibile e creeremo due thread di quella classe e li eseguiremo di conseguenza.
Inoltre, stiamo seguendo due lezioni,
- Uno che implementerà l'interfaccia eseguibile e
- Un altro che avrà il metodo principale e verrà eseguito di conseguenza.
package demotest; public class GuruThread2 { public static void main(String[] args) { // TODO Auto-generated method stub GuruThread3 threadguru1 = new GuruThread3("guru1"); threadguru1.start(); GuruThread3 threadguru2 = new GuruThread3("guru2"); threadguru2.start(); } } class GuruThread3 implements Runnable { Thread guruthread; private String guruname; GuruThread3(String name) { guruname = name; } @Override public void run() { System.out.println("Thread running" + guruname); for (int i = 0; i < 4; i++) { System.out.println(i); System.out.println(guruname); try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println("Thread has been interrupted"); } } } public void start() { System.out.println("Thread started"); if (guruthread == null) { guruthread = new Thread(this, guruname); guruthread.start(); } } }
Spiegazione del codice:
- Riga di codice 2: Qui stiamo prendendo una classe "GuruThread2" che conterrà il metodo principale.
- Riga di codice 4: Qui stiamo prendendo un metodo principale della classe.
- Riga di codice 6-7: Qui stiamo creando un'istanza della classe GuruThread3 (che viene creata nelle righe seguenti del codice) come "threadguru1" e stiamo iniziando il thread.
- Riga di codice 8-9: Qui stiamo creando un'altra istanza della classe GuruThread3 (che viene creata nelle righe seguenti del codice) come "threadguru2" e stiamo iniziando il thread.
- Riga di codice 11: Qui stiamo creando una classe "GuruThread3" che implementa l'interfaccia eseguibile (dovrebbe essere implementata da qualsiasi classe le cui istanze devono essere eseguite dal thread).
- Riga di codice 13-14: stiamo prendendo due variabili di classe di cui una è del tipo classe thread e l'altra della classe stringa.
- Riga di codice 15-18: stiamo sovrascrivendo il costruttore GuruThread3, che accetta un argomento come tipo di stringa (che è il nome del thread) che viene assegnato alla variabile di classe guruname e quindi viene memorizzato il nome del thread.
- Riga di codice 20: Qui stiamo sovrascrivendo il metodo run() dell'interfaccia eseguibile.
- Riga di codice 21: Stiamo emettendo il nome del thread utilizzando l'istruzione println.
- Riga di codice 22-31: Qui stiamo usando un ciclo for con il contatore inizializzato su 0, e non dovrebbe essere inferiore a 4 (possiamo prendere qualsiasi numero quindi qui il ciclo verrà eseguito 4 volte) e incrementando il contatore. Stiamo stampando il nome del thread e anche mettendo il thread in pausa per 1000 millisecondi all'interno di un blocco try-catch poiché il metodo sleep ha sollevato un'eccezione controllata.
- Riga di codice 33: Qui stiamo sovrascrivendo il metodo di avvio dell'interfaccia eseguibile.
- Riga di codice 35: Stiamo emettendo il testo "Thread avviato".
- Riga di codice 36-40: Qui stiamo prendendo una condizione if per verificare se la variabile di classe guruthread ha valore o no. Se è null, stiamo creando un'istanza utilizzando la classe thread che accetta il nome come parametro (il cui valore è stato assegnato nel costruttore). Dopodiché il thread viene avviato utilizzando il metodo start().
Quando esegui il codice sopra ottieni il seguente output:
Uscita:
Ci sono due thread, quindi riceviamo due volte il messaggio "Thread avviato".
Otteniamo i nomi dei thread così come li abbiamo generati.
Entra nel ciclo for dove stiamo stampando il contatore e il nome del thread e il contatore inizia con 0.
Il ciclo viene eseguito tre volte e nel frattempo il thread viene sospeso per 1000 millisecondi.
Quindi, prima otteniamo guru1 poi guru2 poi di nuovo guru2 perché il thread dorme qui per 1000 millisecondi e poi dopo guru1 e ancora guru1, il thread dorme per 1000 millisecondi, quindi otteniamo guru2 e poi guru1.
Sintesi
In questo tutorial abbiamo visto le applicazioni multithread in Java e come utilizzare thread singolo e multiplo Java.
- Spiegare il multithreading Java: nel multithreading, gli utenti non vengono bloccati poiché i thread sono indipendenti e possono eseguire più operazioni contemporaneamente
- Le varie fasi del ciclo di vita del filo sono,
- Nuovo
- eseguibile
- corsa
- In attesa
- Morto
- Abbiamo anche imparato a conoscere dati tra i thread, che aiutano l'applicazione a funzionare senza problemi.
- Programmazione multithread in Java semplifica molte più attività applicative.