Compared
Shortcoming:
Implementing a queue-based lock
Each thread has:
Node myNode
node “owned” by threadNode myPred
node owned by predecessor threadEach Node
has:
boolean locked
:
myNode.locked = true
signals I want/have lockmyNode.locked = false
signals I have released lockThread acquires lock when myPred.locked
is false
When a node locks, 2 things happen:
tail
myPred
In what order should these updates occur?
Use AtomicReference<...>
class
getAndSet
method
myPred = tail.getAndSet(myNode)
Each thread has own variables
myNode
myPred
How do we get different variables for each thread???
Java (generic) class: ThreadLocal<T>
T
for each threadThreadLocal
methods:
T get()
returns current thread’s copy of variableprotected T initialValue()
returns current thread’s initial value
@Override
this to initializevoid set(T value)
set value of current thread’s copyMake a MyClass
instance for each thread:
public class TLObjects {
private ThreadLocal<MyClass> myInstance =
new ThreadLocal<MyClass>() {
@Override
protected MyClass initialValue() {
return new MyClass(...args...);
}
};
}
Uses anonymous inner class construction
{...}
...
” implements/overrides methodsThreadId
Make a class that assigns IDs to threads sequentially
Fields:
static AtomicInteger
that stores next ID to be assignedstatic ThreadLocal<Integer>
that stores thread’s IDMethods:
static int get()
returns value of thread’s IDWhy is everything static
?
ThreadID
in CodeThreadLocal
for CLHLock
Fields:
tail
node
AtomicReference
to getAndSet
atomicallymyNode
, the Node
I initially ownpredNode
, initially null
Methods:
lock()
myNode.locked = ture
tail
nodetail
to myNode
myPred.locked == false
unlock()
myNode.locked = false
(releases lock)myNode
to myPred
CLHLock