-
Notifications
You must be signed in to change notification settings - Fork 0
/
TASLock.java
55 lines (50 loc) · 1.7 KB
/
TASLock.java
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
import java.util.concurrent.atomic.*;
// Test-and-set Lock uses an atomic value for
// indicating that some thread has engaged the lock
// and is executing its critical section (CS).
//
// Each thread that wants to enter CS tries
// to engage lock, and checks to see if it was
// the one who managed to engage it (with an
// atomic operation). This has no effect if
// it was already engaged. If it managed to
// engage it, it proceeds to its CS, otherwise
// it just retries.
//
// Once the thread is done with CS, it simply
// disengages the lock.
//
// As all thread repeatedly attempt to engage the
// lock for themselves, it leads a storm on the
// processor memory bus (since the atomic operation
// ignores the cache). Since bus traffic is always
// high, it makes it difficult for the lock holder
// to disengage his lock (due to traffic). Also
// this scheme does not provide first-come-first-
// served fairness. Hence, this type of lock is
// only suitable for educational purposes.
class TASLock extends AbstractLock {
AtomicBoolean locked;
// locked: indicates if lock is engaged
public TASLock() {
locked = new AtomicBoolean(false);
}
// 1. When thread wants to access critical
// section, it tries to engage lock, for
// itself, with an atomic operation. This
// has no effect if it was already engaged.
// If it managed to engage it, it proceeds
// to its CS.
// 2. If not, it retries again.
@Override
public void lock() {
while(locked.getAndSet(true)) Thread.yield(); // 1, 2
}
// 1. When a thread is done with its critical
// section, it simply sets the "locked" state
// to false.
@Override
public void unlock() {
locked.set(false); // 1
}
}