En aquest tema, explorarem el cicle de vida dels fils en Java. Els fils són una part fonamental de la programació concurrent i multithreading, i comprendre el seu cicle de vida és essencial per escriure aplicacions eficients i segures.
Conceptes Clau
- Cicle de Vida d'un Fil: Els fils passen per diversos estats des del moment en què es creen fins que finalitzen.
- Estats dels Fils: Els estats principals són: New, Runnable, Blocked, Waiting, Timed Waiting, i Terminated.
- Mètodes Clau:
start()
,run()
,sleep()
,wait()
,notify()
,notifyAll()
,join()
.
Estats dels Fils
Els fils en Java poden estar en un dels següents estats:
Estat | Descripció |
---|---|
New | El fil ha estat creat però encara no ha començat. |
Runnable | El fil està preparat per executar-se i està esperant que el planificador de fils li assigni temps de CPU. |
Blocked | El fil està esperant per obtenir un monitor de bloqueig. |
Waiting | El fil està esperant indefinidament fins que un altre fil el notifiqui. |
Timed Waiting | El fil està esperant durant un període de temps específic. |
Terminated | El fil ha finalitzat la seva execució. |
Diagrama del Cicle de Vida dels Fils
Mètodes Clau
start()
El mètode start()
inicia l'execució d'un fil. Quan es crida a aquest mètode, el fil passa de l'estat New a l'estat Runnable.
run()
El mètode run()
conté el codi que s'executarà en el fil. Aquest mètode és invocat internament per start()
.
sleep(long millis)
El mètode sleep()
fa que el fil actual es posi en estat Timed Waiting durant el temps especificat en mil·lisegons.
wait()
El mètode wait()
fa que el fil actual es posi en estat Waiting fins que un altre fil cridi a notify()
o notifyAll()
en el mateix objecte.
notify()
i notifyAll()
Els mètodes notify()
i notifyAll()
desperten un o tots els fils que estan esperant en el mateix objecte, respectivament.
join()
El mètode join()
fa que el fil actual esperi fins que el fil en el qual es crida a join()
finalitzi.
Exemple Pràctic
A continuació, es mostra un exemple pràctic que il·lustra el cicle de vida dels fils:
class SimpleThread extends Thread { public void run() { System.out.println(Thread.currentThread().getName() + " is running."); try { Thread.sleep(1000); // El fil es posa en estat Timed Waiting } catch (InterruptedException e) { System.out.println(e); } System.out.println(Thread.currentThread().getName() + " has finished."); } } public class ThreadLifecycleDemo { public static void main(String[] args) { SimpleThread t1 = new SimpleThread(); SimpleThread t2 = new SimpleThread(); System.out.println("State of t1 after creating it: " + t1.getState()); // New t1.start(); t2.start(); System.out.println("State of t1 after calling start(): " + t1.getState()); // Runnable try { t1.join(); // El fil principal espera que t1 finalitzi t2.join(); // El fil principal espera que t2 finalitzi } catch (InterruptedException e) { System.out.println(e); } System.out.println("State of t1 after it has finished: " + t1.getState()); // Terminated } }
Exercicis Pràctics
Exercici 1: Crear i Executar Fils
- Crea una classe que implementi
Runnable
i sobreescriu el mètoderun()
. - Crea i inicia diversos fils utilitzant aquesta classe.
- Observa i imprimeix els estats dels fils en diferents punts del seu cicle de vida.
Exercici 2: Sincronització de Fils
- Crea una classe amb un mètode sincronitzat que incrementi un comptador.
- Crea diversos fils que cridin a aquest mètode.
- Utilitza
wait()
inotify()
per coordinar els fils.
Solucions
Solució a l'Exercici 1
class MyRunnable implements Runnable { public void run() { System.out.println(Thread.currentThread().getName() + " is running."); try { Thread.sleep(500); } catch (InterruptedException e) { System.out.println(e); } System.out.println(Thread.currentThread().getName() + " has finished."); } } public class ThreadExercise1 { public static void main(String[] args) { Thread t1 = new Thread(new MyRunnable()); Thread t2 = new Thread(new MyRunnable()); System.out.println("State of t1 after creating it: " + t1.getState()); // New t1.start(); t2.start(); System.out.println("State of t1 after calling start(): " + t1.getState()); // Runnable try { t1.join(); t2.join(); } catch (InterruptedException e) { System.out.println(e); } System.out.println("State of t1 after it has finished: " + t1.getState()); // Terminated } }
Solució a l'Exercici 2
class Counter { private int count = 0; public synchronized void increment() { count++; System.out.println(Thread.currentThread().getName() + " incremented count to: " + count); } } class CounterRunnable implements Runnable { private Counter counter; public CounterRunnable(Counter counter) { this.counter = counter; } public void run() { for (int i = 0; i < 5; i++) { counter.increment(); try { Thread.sleep(100); } catch (InterruptedException e) { System.out.println(e); } } } } public class ThreadExercise2 { public static void main(String[] args) { Counter counter = new Counter(); Thread t1 = new Thread(new CounterRunnable(counter)); Thread t2 = new Thread(new CounterRunnable(counter)); t1.start(); t2.start(); try { t1.join(); t2.join(); } catch (InterruptedException e) { System.out.println(e); } } }
Conclusió
En aquest tema, hem explorat el cicle de vida dels fils en Java, incloent els diferents estats pels quals passen i els mètodes clau que controlen aquests estats. També hem vist exemples pràctics i exercicis per reforçar els conceptes apresos. Amb aquesta comprensió, estàs preparat per gestionar fils de manera efectiva en les teves aplicacions Java.
Curs de Programació en Java
Mòdul 1: Introducció a Java
- Introducció a Java
- Configuració de l'Entorn de Desenvolupament
- Sintaxi i Estructura Bàsica
- Variables i Tipus de Dades
- Operadors
Mòdul 2: Flux de Control
Mòdul 3: Programació Orientada a Objectes
- Introducció a la POO
- Classes i Objectes
- Mètodes
- Constructors
- Herència
- Polimorfisme
- Encapsulació
- Abstracció
Mòdul 4: Programació Orientada a Objectes Avançada
Mòdul 5: Estructures de Dades i Col·leccions
Mòdul 6: Gestió d'Excepcions
Mòdul 7: Entrada/Sortida de Fitxers
- Lectura de Fitxers
- Escriptura de Fitxers
- Fluxos de Fitxers
- BufferedReader i BufferedWriter
- Serialització
Mòdul 8: Multithreading i Concurrència
- Introducció al Multithreading
- Creació de Fils
- Cicle de Vida dels Fils
- Sincronització
- Utilitats de Concurrència
Mòdul 9: Xarxes
- Introducció a les Xarxes
- Sockets
- ServerSocket
- DatagramSocket i DatagramPacket
- URL i HttpURLConnection