-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathLivelock.java
More file actions
79 lines (65 loc) · 2.22 KB
/
Livelock.java
File metadata and controls
79 lines (65 loc) · 2.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package by.andd3dfx.multithreading;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
/**
* Taken from <a href="https://github.com/proselytear/javaconcurrency">this repo</a>
*/
public class Livelock {
@Getter
@Setter
@AllArgsConstructor
public static class Spoon {
private Eater owner;
public synchronized void use() {
System.out.printf("%s has eaten!", owner.getName());
}
}
@Getter
public static class Eater {
private String name;
private boolean isHungry;
public Eater(String n) {
name = n;
isHungry = true;
}
public void eatWith(Spoon spoon, Eater spouse) {
while (isHungry) {
// Don't have the spoon, so wait patiently for spouse.
if (spoon.getOwner() != this) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
continue;
}
continue;
}
// If spouse is hungry, insist upon passing the spoon.
if (spouse.isHungry()) {
System.out.printf(
"%s: You eat first my darling %s!%n",
name, spouse.getName());
spoon.setOwner(spouse);
continue;
}
// Spouse wasn't hungry, so finally eat
spoon.use();
isHungry = false;
System.out.printf(
"%s: I am stuffed, my darling %s!%n",
name, spouse.getName());
spoon.setOwner(spouse);
}
}
}
public void makeLivelock() {
Eater husband = new Eater("Bob");
Eater wife = new Eater("Alice");
Spoon s = new Spoon(husband);
Thread thread1 = new Thread(() -> husband.eatWith(s, wife));
Thread thread2 = new Thread(() -> wife.eatWith(s, husband));
thread1.start();
thread2.start();
while (thread1.isAlive() || thread2.isAlive()) ;
}
}