22. public final class Node<T> {
private final Node<T> next;
private final T value;
public Node(Node<T> next, T value) {
this.next = next;
this.value = value;
}
public Node<T> getNext() {
return next;
}
public T getValue() {
return value;
}
}
A toy problem – stack
29. A toy problem – stack push
class Node<T>(val next: Node<T>?, val value: T)
class LinkedStack<T> {
private var top: Node<T>? = null
fun push(value: T) {
top = Node(top, value)
}
}
30. A toy problem – stack push
class Node<T>(val next: Node<T>?, val value: T)
class LinkedStack<T> {
private var top: Node<T>? = null
fun push(value: T) {
top = Node(top, value)
}
}
31. A toy problem – stack push
class Node<T>(val next: Node<T>?, val value: T)
class LinkedStack<T> {
private var top: Node<T>? = null
fun push(value: T) {
top = Node(top, value)
}
}
36. A toy problem – stack pop
class Node<T>(val next: Node<T>?, val value: T)
class LinkedStack<T> {
private var top: Node<T>? = null
fun push(value: T) {
top = Node(top, value)
}
fun pop(): T? {
val cur = top ?: return null
top = cur.next
return cur.value
}
}
37. A toy problem – stack
class Node<T>(val next: Node<T>?, val value: T)
class LinkedStack<T> {
private var top: Node<T>? = null
fun push(value: T) {
top = Node(top, value)
}
fun pop(): T? {
val cur = top ?: return null
top = cur.next
return cur.value
}
}
42. A toy problem – synchronized stack
class Node<T>(val next: Node<T>?, val value: T)
class LinkedStack<T> {
private var top: Node<T>? = null
@Synchronized
fun push(value: T) {
top = Node(top, value)
}
@Synchronized
fun pop(): T? {
val cur = top ?: return null
top = cur.next
return cur.value
}
}
59. Using AtomicReference
class LockFree<T> {
private val top = AtomicReference<Node<T>?>(null)
fun push(value: T) {
while (true) {
val cur = top.get()
val upd = Node(cur, value)
if (top.compareAndSet(cur, upd)) return
}
}
}
60. Using AtomicReference
class LockFree<T> {
private val top = AtomicReference<Node<T>?>(null)
fun push(value: T) {
while (true) {
val cur = top.get()
val upd = Node(cur, value)
if (top.compareAndSet(cur, upd)) return
}
}
}
61. Using AtomicReference - push
class LockFree<T> {
private val top = AtomicReference<Node<T>?>(null)
fun push(value: T) {
while (true) {
val cur = top.get()
val upd = Node(cur, value)
if (top.compareAndSet(cur, upd)) return
}
}
}
1
62. Using AtomicReference - push
class LockFree<T> {
private val top = AtomicReference<Node<T>?>(null)
fun push(value: T) {
while (true) {
val cur = top.get()
val upd = Node(cur, value)
if (top.compareAndSet(cur, upd)) return
}
}
}
1
2
63. Using AtomicReference
class LockFree<T> {
private val top = AtomicReference<Node<T>?>(null)
fun push(value: T) {
while (true) {
val cur = top.get()
val upd = Node(cur, value)
if (top.compareAndSet(cur, upd)) return
}
}
}
1
2
3
64. Using AtomicReference - push
1
2
3
class LockFree<T> {
private val top = AtomicReference<Node<T>?>(null)
fun push(value: T) {
while (true) {
val cur = top.get()
val upd = Node(cur, value)
if (top.compareAndSet(cur, upd)) return
}
}
}
66. Using AtomicReference - pop
class LockFree<T> {
private val top = AtomicReference<Node<T>?>(null)
fun push(value: T) { … }
fun pop(): T? {
while (true) {
val cur = top.get() ?: return null
if (top.compareAndSet(cur, cur.next)) return cur.value
}
}
}
70. Using AtomicReferenceFieldUpdater
package java.util.concurrent.atomic;
/** @since 1.5 */
public abstract class AtomicReferenceFieldUpdater<T,V> {
public static <U,W> AtomicReferenceFieldUpdater<U,W> newUpdater(
Class<U> tclass, Class<W> vclass, String fieldName;
public abstract boolean compareAndSet(T obj, V expect, V update;
}
79. Using AtomicFU J
private val top = atomic<Node<T>?>(null)
if (top.compareAndSet(cur, upd)) return
Code like
AtomicReference
80. Using AtomicFU J
private val top = atomic<Node<T>?>(null)
if (top.compareAndSet(cur, upd)) return
Bytecode
Code like
AtomicReference
compile
81. Using AtomicFU J
private val top = atomic<Node<T>?>(null)
if (top.compareAndSet(cur, upd)) return
Bytecode
Code like
AtomicReference
AtomicReferenceFUcompile atomicFU
82. Using AtomicFU J
private val top = atomic<Node<T>?>(null)
if (top.compareAndSet(cur, upd)) return
Bytecode
Code like
AtomicReference
VarHandlecompile atomicFU
87. Too toy of a problem?
class LinkedStack<T> {
private var top: Node<T>? = null
@Synchronized
fun push(value: T) { … }
@Synchronized
fun pop(): T? {
val cur = top ?: return null
top = cur.next
return cur.value
}
}
88. Too toy of a problem – make it more real?
class LinkedStack<T> {
private var top: Node<T>? = null
@Synchronized
fun push(value: T) { … }
@Synchronized
fun pop(): T? {
val cur = top ?: return null
top = cur.next
Blackhole.consumeCPU(100L)
return cur.value
}
}
89. Too toy of a problem – make it more real?
class LockFree<T> {
private val top = atomic<Node<T>?>(null)
fun push(value: T) { … }
fun pop(): T? {
while (true) {
val cur = top.value ?: return null
Blackhole.consumeCPU(100L)
if (top.compareAndSet(cur, cur.next)) return cur.value
}
}
}