09 august 2024

Exemple Deadlock & Livelock

Deadlock

Cand doua sau mai multe fire de executie sunt blocate in asteptarea eliberarii unor resurse de care au nevoie. Solutie: how to prevent deadlock in Java.

private static void deadlock() {
final String res1 = "Resource_1";
final String res2 = "Resource_2";

Thread t1 = new Thread(() -> {
synchronized (res1) {
System.out.println("[t1] acquired access to res1");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (res2) {
System.out.println("[t1] Yay! escaped deadlock."); // not happening
}
}
});
Thread t2 = new Thread(() -> {
synchronized (res2) {
System.out.println("[t2] acquired access to res2");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (res1) {
System.out.println("[t2] Yay! escaped deadlock.");
}
}
});

t1.start();
t2.start();
}

Livelock

Doua sau mai multe fire de executie isi cedeaza dreptul de a rula in favoarea celorlalte astfel ajungand sa nu ruleze niciodata, iar aplicatia nu progreseaza. Solutie: schimbarea logicii.

static class Spoon {
Diner owner;

public Spoon (Diner firstOwner) {
this.owner = firstOwner;
}

synchronized void setOwner(Diner owner) {
this.owner = owner;
}

synchronized void use() {
System.out.println(owner.name + " just ate!");
}
}

static class Diner {
String name;
boolean isHungry;

public Diner (String name) {
this.name = name;
this.isHungry = true;
}

public void eatWith (Spoon spoon, Diner spouse) {
while (isHungry) {
if (spoon.owner != this) {
// wait for a while for the spoon to be released
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}

// after wait, try to give the spoon to the spouse if she's hungry
if (spouse.isHungry) {
System.out.println("[" + name + "] Eat, baby, eat!");
spoon.owner = spouse;
} else {
// finally
spoon.use();
isHungry = false;
System.out.println("[" + name + "] Finally ate!!!"); // never
spoon.owner = spouse;
}
}
}
}

private static void livelock() {
final Diner husband = new Diner("Adnan");
final Diner wife = new Diner("Hannan");
Spoon spoon = new Spoon(wife);

try {
new Thread(() -> husband.eatWith(spoon, wife)).start();
Thread.sleep(1500);
new Thread(() -> wife.eatWith(spoon, husband)).start();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}

Niciun comentariu: