Concorrenza Java - Panoramica
Java è un linguaggio di programmazione multi-thread che significa che possiamo sviluppare programmi multi-thread utilizzando Java. Un programma multi-thread contiene due o più parti che possono essere eseguite contemporaneamente e ciascuna parte può gestire un'attività diversa allo stesso tempo, facendo un uso ottimale delle risorse disponibili specialmente quando il tuo computer ha più CPU.
Per definizione, il multitasking è quando più processi condividono risorse di elaborazione comuni come una CPU. Il multi-threading estende l'idea del multitasking in applicazioni in cui è possibile suddividere operazioni specifiche all'interno di una singola applicazione in singoli thread. Ciascuno dei thread può essere eseguito in parallelo. Il sistema operativo divide il tempo di elaborazione non solo tra le diverse applicazioni, ma anche tra ogni thread all'interno di un'applicazione.
Il multi-threading consente di scrivere in un modo in cui più attività possono procedere contemporaneamente nello stesso programma.
Ciclo di vita di un filo
Un filo attraversa varie fasi del suo ciclo di vita. Ad esempio, un thread nasce, avviato, viene eseguito e quindi muore. Il diagramma seguente mostra il ciclo di vita completo di un thread.
Di seguito sono riportate le fasi del ciclo di vita:
New- Un nuovo thread inizia il suo ciclo di vita nel nuovo stato. Rimane in questo stato finché il programma non avvia il thread. Viene anche chiamatoborn thread.
Runnable- Dopo l'avvio di un thread appena nato, il thread diventa eseguibile. Si considera che un thread in questo stato stia eseguendo la sua attività.
Waiting- A volte, un thread passa allo stato di attesa mentre il thread attende che un altro thread esegua un'attività. Un thread torna allo stato eseguibile solo quando un altro thread segnala al thread in attesa di continuare l'esecuzione.
Timed Waiting- Un thread eseguibile può entrare nello stato di attesa a tempo per un intervallo di tempo specificato. Un thread in questo stato torna allo stato eseguibile quando scade l'intervallo di tempo o quando si verifica l'evento che è in attesa.
Terminated (Dead) - Un thread eseguibile entra nello stato terminato quando completa la sua attività o termina in altro modo.
Priorità thread
Ogni thread Java ha una priorità che aiuta il sistema operativo a determinare l'ordine in cui sono pianificati i thread.
Le priorità dei thread Java sono nell'intervallo tra MIN_PRIORITY (una costante di 1) e MAX_PRIORITY (una costante di 10). Per impostazione predefinita, a ogni thread viene assegnata la priorità NORM_PRIORITY (una costante di 5).
I thread con priorità più alta sono più importanti per un programma e dovrebbero essere allocati tempo processore prima dei thread con priorità più bassa. Tuttavia, le priorità dei thread non possono garantire l'ordine in cui vengono eseguiti i thread e sono molto dipendenti dalla piattaforma.
Crea un thread implementando un'interfaccia eseguibile
Se la tua classe è concepita per essere eseguita come thread, puoi ottenere ciò implementando un file Runnableinterfaccia. Dovrai seguire tre passaggi fondamentali:
Passo 1
Come primo passo, è necessario implementare un metodo run () fornito da un file Runnableinterfaccia. Questo metodo fornisce un punto di ingresso per il thread e inserirai la tua logica aziendale completa all'interno di questo metodo. Di seguito è riportata una semplice sintassi del metodo run ():
public void run( )
Passo 2
Come secondo passaggio, istanzerai un file Thread oggetto utilizzando il seguente costruttore:
Thread(Runnable threadObj, String threadName);
Dove, threadObj è un'istanza di una classe che implementa ilRunnable interfaccia e threadName è il nome dato al nuovo thread.
Passaggio 3
Una volta creato un oggetto Thread, puoi avviarlo chiamando start()metodo, che esegue una chiamata al metodo run (). Di seguito è riportata una semplice sintassi del metodo start ():
void start();
Example
Ecco un esempio che crea un nuovo thread e inizia a eseguirlo:
class RunnableDemo implements Runnable {
private Thread t;
private String threadName;
RunnableDemo(String name) {
threadName = name;
System.out.println("Creating " + threadName );
}
public void run() {
System.out.println("Running " + threadName );
try {
for(int i = 4; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);
// Let the thread sleep for a while.
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}
public void start () {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
}
public class TestThread {
public static void main(String args[]) {
RunnableDemo R1 = new RunnableDemo("Thread-1");
R1.start();
RunnableDemo R2 = new RunnableDemo("Thread-2");
R2.start();
}
}
Questo produrrà il seguente risultato:
Output
Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.
Creare un thread estendendo una classe di thread
Il secondo modo per creare un thread è creare una nuova classe che si estende Threadclasse utilizzando i seguenti due semplici passaggi. Questo approccio fornisce una maggiore flessibilità nella gestione di più thread creati utilizzando i metodi disponibili nella classe Thread.
Passo 1
Dovrai eseguire l'override run( )metodo disponibile nella classe Thread. Questo metodo fornisce un punto di ingresso per il thread e inserirai la tua logica aziendale completa all'interno di questo metodo. Di seguito è riportata una semplice sintassi del metodo run ():
public void run( )
Passo 2
Una volta creato l'oggetto Thread, puoi avviarlo chiamando start()metodo, che esegue una chiamata al metodo run (). Di seguito è riportata una semplice sintassi del metodo start ():
void start( );
Example
Ecco il programma precedente riscritto per estendere il thread -
class ThreadDemo extends Thread {
private Thread t;
private String threadName;
ThreadDemo(String name) {
threadName = name;
System.out.println("Creating " + threadName );
}
public void run() {
System.out.println("Running " + threadName );
try {
for(int i = 4; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);
// Let the thread sleep for a while.
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
System.out.println("Thread " + threadName + " exiting.");
}
public void start () {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
}
public class TestThread {
public static void main(String args[]) {
ThreadDemo T1 = new ThreadDemo("Thread-1");
T1.start();
ThreadDemo T2 = new ThreadDemo("Thread-2");
T2.start();
}
}
Questo produrrà il seguente risultato:
Output
Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.