Fils a Java
L’API de baix nivell de Java es basa en l’objecte Thread, que pot tenir una sèrie d’estats.
- NEW: Un fil que no s’ha iniciat.
- RUNNABLE: Un fil que s’està executant a la JVM. És possible que no tingui la CPU.
- BLOCKED: Un fil que està esperant per entrar a un bloc sincronitzat (esperant un monitor lock).
- WAITING: Un fil que espera indefinidament per un altre (operacions wait, join).
- TIMED_WAITING: Un fil que espera un cert temps per un altre (operacions sleep, wait, join).
- TERMINATED: Un fil que ha acabat. No es pot tornar a executar.
Podem crear un fil de dues maneres:
- Estendre la classe Thread i reescriure el mètode “run” (millor no utilitzar aquest mètode).
- Implementar la interfície Runnable i el seu mètode “run”. Llavors, crear un Thread passant aquest objecte al constructor:
new Thread(new MyRunnable())
Un cop tenim el Thread, el podem executar mitjançant el seu mètode start(), que farà canviar el seu estat de NEW a RUNNABLE.
Per als exemples que veurem a continuació, utilitzarem la següent utility class:
public class Threads {
private static long start = System.currentTimeMillis();
private Threads() {}
public static void log(String message) {
System.out.println(String.format("%6d %-10s %s",
System.currentTimeMillis() - start,
Thread.currentThread().getName(), message));
}
public static void spend(long millis) {
long startTime = System.currentTimeMillis();
while (System.currentTimeMillis() - startTime < millis);
}
public static void rest(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
Els seus mètodes poden cridar-se després de fer un import static Threads.*;.
A continuació, podem veure un exemple de creació d’un fil anomenat “fil” des del fil principal, “main”. Mostra l’estat del fil “child” abans i després de la seva execució.

Aquest seria el codi:
public class StatesThread {
static class MyRunnable implements Runnable {
@Override
public void run() {
log("spending");
spend(750);
log("resting");
rest(750);
log("ending");
}
}
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable(), "child");
log(thread.getState().name());
thread.start();
rest(250);
log(thread.getState().name());
rest(875);
log(thread.getState().name());
rest(500);
log(thread.getState().name());
}
}
Aquesta podria ser una sortida per pantalla possible:
0 main NEW
8 child spending
258 main RUNNABLE
758 child resting
1133 main TIMED_WAITING
1508 child ending
1633 main TERMINATED
Aquest exemple no presenta dificultats, ja que no es comparteix cap dada. Tampoc s’utilitza cap mecanisme de sincronització entre els dos fils.