El multithreading és una tècnica de programació que permet l'execució concurrent de múltiples fils (threads) dins d'un mateix procés. Això pot millorar significativament el rendiment d'una aplicació, especialment en sistemes amb múltiples nuclis de CPU. En aquest tema, aprendrem els conceptes bàsics del multithreading en Java, com crear i gestionar fils, i els avantatges i desavantatges d'utilitzar aquesta tècnica.

Conceptes Clau

  1. Fil (Thread): Un fil és la unitat més petita d'execució dins d'un procés. Cada fil té el seu propi conjunt de registres, pila i estat, però comparteix la memòria i altres recursos amb altres fils del mateix procés.
  2. Procés: Un procés és un programa en execució que pot contenir múltiples fils.
  3. Concurrència: La capacitat d'executar múltiples tasques al mateix temps.
  4. Paral·lelisme: L'execució simultània de múltiples tasques en múltiples nuclis de CPU.

Avantatges del Multithreading

  • Millora del Rendiment: Permet aprofitar millor els recursos del sistema, especialment en sistemes amb múltiples nuclis de CPU.
  • Millor Resposta: Les aplicacions poden respondre més ràpidament a les entrades de l'usuari, ja que les tasques de fons es poden executar en fils separats.
  • Simplicitat en la Gestió de Tasques: Facilita la gestió de tasques que es poden executar de manera independent.

Desavantatges del Multithreading

  • Complexitat: La programació multithreading pot ser complexa i difícil de depurar.
  • Condicions de Cursa: Problemes que es produeixen quan múltiples fils accedeixen i modifiquen dades compartides de manera concurrent.
  • Bloquejos: Situacions en què dos o més fils es bloquegen mútuament esperant recursos que l'altre té.

Creació de Fils en Java

En Java, hi ha dues maneres principals de crear fils:

  1. Extenent la classe Thread:

    class MyThread extends Thread {
        public void run() {
            System.out.println("El fil està en execució.");
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            MyThread thread = new MyThread();
            thread.start(); // Inicia el fil
        }
    }
    
  2. Implementant la interfície Runnable:

    class MyRunnable implements Runnable {
        public void run() {
            System.out.println("El fil està en execució.");
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            Thread thread = new Thread(new MyRunnable());
            thread.start(); // Inicia el fil
        }
    }
    

Explicació del Codi

  • Extenent la classe Thread:

    • Creem una classe que extén Thread i sobreescrivim el mètode run().
    • Creem una instància de la nostra classe i cridem al mètode start(), que internament crida al mètode run().
  • Implementant la interfície Runnable:

    • Creem una classe que implementa la interfície Runnable i sobreescrivim el mètode run().
    • Creem una instància de Thread passant una instància de la nostra classe Runnable al constructor de Thread.
    • Cridem al mètode start() de l'objecte Thread.

Exercicis Pràctics

Exercici 1: Crear un Fil que Imprimeixi Nombres

Descripció: Crea un fil que imprimeixi els nombres de l'1 al 10.

Solució:

class NumberThread extends Thread {
    public void run() {
        for (int i = 1; i <= 10; i++) {
            System.out.println(i);
        }
    }
}

public class Main {
    public static void main(String[] args) {
        NumberThread thread = new NumberThread();
        thread.start();
    }
}

Exercici 2: Crear un Fil que Imprimeixi un Missatge

Descripció: Crea un fil que imprimeixi "Hola, món!" cinc vegades.

Solució:

class MessageRunnable implements Runnable {
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("Hola, món!");
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Thread thread = new Thread(new MessageRunnable());
        thread.start();
    }
}

Errors Comuns i Consells

  • No cridar al mètode run() directament: Sempre utilitza el mètode start() per iniciar un fil. Cridar al mètode run() directament no crearà un nou fil.
  • Sincronització: Quan múltiples fils accedeixen a dades compartides, assegura't d'utilitzar mecanismes de sincronització per evitar condicions de cursa.

Resum

En aquesta secció, hem après els conceptes bàsics del multithreading en Java, incloent com crear i gestionar fils. Hem vist els avantatges i desavantatges del multithreading i hem practicat amb alguns exercicis bàsics. En la següent secció, explorarem com crear fils en més detall i com gestionar el seu cicle de vida.

Curs de Programació en Java

Mòdul 1: Introducció a Java

Mòdul 2: Flux de Control

Mòdul 3: Programació Orientada a Objectes

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

Mòdul 8: Multithreading i Concurrència

Mòdul 9: Xarxes

Mòdul 10: Temes Avançats

Mòdul 11: Frameworks i Llibreries de Java

Mòdul 12: Construcció d'Aplicacions del Món Real

© Copyright 2024. Tots els drets reservats