You are on page 1of 63

...........................................................................................................................................................

4
Java ...................................................................................................................... 6
1.1

1.2

1.3

1.4

1.5

ConcurrentHashMap .......................................................................................... 6
1.1.1

ConcurrentHashMap ............................................................................. 6

1.1.2

ConcurrentHashMap .............................................................................. 7

1.1.3

ConcurrentHashMap .......................................................................................... 7

1.1.4

ConcurrentHashMap ...................................................................................... 9

1.1.5

Segment .............................................................................................................. 11

1.1.6

ConcurrentHashMap get ................................................................................. 12

1.1.7

ConcurrentHashMap put ................................................................................. 12

1.1.8

ConcurrentHashMap size ................................................................................ 13

ConcurrentLinkedQueue .................................................................................. 13
1.2.1

ConcurrentLinkedQueue .................................................................................. 14

1.2.2

ConcurrentLinkedQueue .................................................................................. 14

1.2.3

......................................................................................................................... 15

1.2.4

......................................................................................................................... 18

Java ...................................................................................................... 19
1.3.1

............................................................................................. 19

1.3.2

............................................................................................................. 20

1.3.3

..................................................................................................... 21

1.3.4

..................................................................................................... 21

1.3.5

............................................................................................................. 22

1.3.6

............................................................................................................. 22

1.3.7

..................................................................................................... 24

1.3.8

............................................................................................................. 25

Java .................................................................................................................. 26
1.4.1

..................................................................................................... 26

1.4.2

Java ...................................................................................................... 27

1.4.3

ArrayBlockingQueue ................................................................................................... 27

1.4.4

LinkedBlockingQueue ................................................................................................. 28

1.4.5

PriorityBlockingQueue ................................................................................................ 28

1.4.6

DelayQueue ................................................................................................................. 28

1.4.7

SynchronousQueue ...................................................................................................... 30

1.4.8

LinkedTransferQueue .................................................................................................. 31

1.4.9

LinkedBlockingDeque ................................................................................................. 31

1.4.10

............................................................................................... 32

Fork/Join .......................................................................................................................... 35
1.5.1

Fork/Join ................................................................................................ 35

1.5.2

............................................................................................................. 36

1.5.3

Fork/Join .................................................................................................. 38

1.5.4

ForkJoin ................................................................................................. 38

1.5.5

Fork/Join .......................................................................................... 40
2

1.5.6
1.6

Fork/Join .......................................................................................... 40

................................................................................................................................. 42

Java ............................................................................................... 43
1.7

1.8

1.9

1.10

Volatile ................................................................................................................. 43
1.7.1

.................................................................................................................... 43

1.7.2

Volatile .................................................................................................... 44

1.7.3

Volatile ............................................................................................... 44

1.7.4

Volatile .................................................................................................... 44

1.7.5

Volatile .................................................................................................... 45

Synchronized ....................................................................................................... 47
1.8.1

................................................................................................................. 47

1.8.2

................................................................................................................. 47

1.8.3

Java .................................................................................................................. 48

1.8.4

..................................................................................................................... 49

1.8.5

......................................................................................................................... 49

1.8.6

..................................................................................................................... 52

1.8.7

......................................................................................................... 53

1.8.8

6 .................................................................................................................. 53

............................................................................................................. 53
1.9.1

..................................................................................................................... 53

1.9.2

......................................................................................... 54

1.9.3

................................................................. 54

1.9.4

............................................................................................. 55

1.9.5

............................................................................................. 56

1.9.6

Java .............................................................................................. 56

1.9.7

CAS .................................................................................... 56

1.9.8

......................................................................................... 60

............................................................................................................................... 60


InfoQ
Java
Java 7 Java 8 JVM
GroovyScalaClojureCeylon JVM Java
Java JVM

Java Java
Java
JVM Java JVM Java
Java
Java SSHStruts
Spring Hibernate
Java SSHSSH Java

InfoQ
Java

synchronized volatile ConcurrentHashMap


ConcurrentLinkedQueue Fork/Join Java

InfoQ Java

Java
4

Java
http://ifeve.com/

Java

InfoQ Java

Java
Java
Doug Lea Java

1.1

ConcurrentHashMap
ConcurrentHashMap HashMap

1.1.1 ConcurrentHashMap
HashMap HashMap put
CPU 100% HashMap
final HashMap<String, String> map = new HashMap<String, String>(2);

Thread t = new Thread(new Runnable() {


@Override
public void run() {
for (int i = 0; i < 10000; i++) {
new Thread(new Runnable() {
@Override
public void run() {
map.put(UUID.randomUUID().toString(), "");
}
}, "ftf" + i).start();
}
}
}, "ftf");
t.start();
t.join();

HashTableHashTable synchronized
HashTable HashTable
HashTable 1 put
2 put get
6


ConcurrentHashMap

1.1.2 ConcurrentHashMap
HashTable HashTable

ConcurrentHashMap

1.1.3 ConcurrentHashMap
ConcurrentHashMap ConcurrentHashMap 9-1 


1-1

ConcurrentHashMap Segment HashEntry Segment


ReentrantLock ConcurrentHashMap HashEntry
ConcurrentHashMap Segment Segment HashMap
Segment HashEntry HashEntry
Segment HashEntry , HashEntry
Segment 7-2

ConcurretnHashMap

Segment[]
HashEntry[]

Segment1

HashEntry1.1

Segment2

HashEntry1.2

HashEntry2.1


1-2

1.1.4 ConcurrentHashMap
ConcurrentHashMap initialCapacityloadFactor, concurrencyLevel
segments segmentShift segmentMask segment HashEntry

segments segmentShiftsegmentMask segments

if (concurrencyLevel > MAX_SEGMENTS)


concurrencyLevel = MAX_SEGMENTS;

// Find power-of-two sizes best matching arguments


int sshift = 0;
int ssize = 1;
while (ssize < concurrencyLevel) {
++sshift;
ssize <<= 1;
}
segmentShift = 32 - sshift;
segmentMask = ssize - 1;
this.segments = Segment.newArray(ssize);

segments ssize concurrencyLevel


segments segments 2 N
power-of-two size concurrencyLevel 2 N
segments concurrencyLevel 1415 16ssize 16
16
concurrencyLevel 65535 segments 65536
16
segmentShift segmentMask segment
sshift ssize 1 concurrencyLevel 161
4 sshift 4segmentShift hash segmentShift
32 sshift 28 32 ConcurrentHashMap hash()
32 segmentMask ssize
1 15 1 ssize 65536 segmentShift
16segmentMask 65535 16 1
Segment initialCapacity ConcurrentHashMap
loadfactor segment
segment
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
int c = initialCapacity / ssize;
if (c * ssize < initialCapacity)
++c;
int cap = 1;
while (cap < c)
cap <<= 1;
for (int i = 0; i < this.segments.length; ++i)
this.segments[i] = new Segment<K,V>(cap, loadFactor);

cap segment HashEntry initialCapacity ssize


c c 1 c 2 N cap 1 2 N
segment threshold(int)cap*loadFactor initialCapacity 16loadfactor
0.75 cap 1threshold

10

1.1.5 Segment
ConcurrentHashMap Segment
Segment ConcurrentHashMap Wang/Jenkins
hash hashCode
private static int hash(int h) {
h += (h << 15) ^ 0xffffcd7d;
h ^= (h >>> 10);
h += (h << 3);
h ^= (h >>> 6);
h += (h << 2) + (h << 14);
return h ^ (h >>> 16);
}

Segment
Segment

System.out.println(Integer.parseInt("0001111", 2) & 15);


System.out.println(Integer.parseInt("0011111", 2) & 15);
System.out.println(Integer.parseInt("0111111", 2) & 15);
System.out.println(Integer.parseInt("1111111", 2) & 15);

15

32 0
01000111011001111101101001001110
11110111010000110000000110111000
01110111011010010100011000111110
10000011000000001100100000011010

ConcurrentHashMap segment
final Segment<K,V> segmentFor(int hash) {
return segments[(hash >>> segmentShift) & segmentMask];
}

segmentShift 28segmentMask 15 32
28 4 hash (hash >>> segmentShift) & segmentMask
11

4157 8 hash

1.1.6 ConcurrentHashMap get


Segment get
segment
public V get(Object key) {
int hash = hash(key.hashCode());
return segmentFor(hash).get(key, hash);
}

get get
HashTable get ConcurrentHashMap get
get volatile Segement
count HashEntry value volatile

get count
value java happen before
volatile volatile get
volatile
transient volatile int count;
volatile V value;

HashEntry Segment
Segment hashcode
HashEntry
Segment HashEntry
hash >>> segmentShift) & segmentMask// Segment hash
int index = hash & (tab.length - 1);// HashEntry hash

1.1.7 ConcurrentHashMap put


put
Put Segment Segment
12

Segment HashEntry
HashEntry
Segment HashEntry threshold
Segment HashMap
HashMap
HashMap

hash ConcurrentHashMap
segment

1.1.8 ConcurrentHashMap size


ConcurrentHashMap Segment
Segment count volatile
Segment count ConcurrentHashMap
Segment count count
size Segment putremove
clean
count count
ConcurrentHashMap 2 Segment Segment
count Segment
ConcurrentHashMap modCount
put , remove clean modCount 1 size
modCount


1.2

ConcurrentLinkedQueue

13


CAS Doug Lea
ConcurrentLinkedQueue

1.2.1 ConcurrentLinkedQueue
ConcurrentLinkedQueue

waitfree CAS Michael &


Scott , Michael & Scott

1.2.2 ConcurrentLinkedQueue
ConcurrentLinkedQueue 8-1


1-3

ConcurrentLinkedQueue head tair Nodeitem


(next) next
head tair head
private transient volatile Node<E> tail = head; 

14

1.2.3
head
tair 8-2


1-4

1 head next 1 tail

head next 1
2

2 1 next 2 tail

2
3

3 tail next 3

4 3 next 4 tail 4


debug head tail
tail tail next
tail tail next tail
next tail

15

CAS
public boolean offer(E e) {
if (e == null) throw new NullPointerException();
//
Node<E> n = new Node<E>(e);
retry:
//
for (;;) {
// tail
Node<E> t = tail;
//p tail
Node<E> p = t;
for (int hops = 0; ; hops++) {
// p
Node<E> next = succ(p);
//next p p next
if (next != null) {
//
if (hops > HOPS && t != tail)
continue retry;
p = next;
}
// p p next
else if (p.casNext(null, n)) {
// tail 1 next tair
tair
if (hops >= HOPS)
casTail(t, n); // tail
return true;
}
// p next , p next p
else {
p = succ(p);
}
}
}
}

CAS
next
16

tail tail
tail tail next if tail
next next tail next p
p next p p next
head p next
final Node<E> succ(Node<E> p) {
Node<E> next = p.getNext();
return (p == next) ? head : next;
}

p.casNext(null, n)
next p null p null

hops
doug lea
public boolean offer(E e) {
if (e == null)
throw new NullPointerException();
Node<E> n = new Node<E>(e);
for (;;) {
Node<E> t = tail;
if (t.casNext(null, n) && casTail(t, n)) {
return true;
}
}
}

tail
CAS tail CAS tail
doug lea hops tail
tail tail
HOPS 1 tail tail CAS tail

volatile volatile volatile


17


private static final int HOPS = 1;

true

1.2.4

head 8-3


1-5

head head head


head head head
hops CAS head

public E poll() {
Node<E> h = head;
// p
Node<E> p = h;
for (int hops = 0;; hops++) {

18

// p
E item = p.getItem();
// p CAS p null,
p
if (item != null && p.casItem(item, null)) {
if (hops >= HOPS) {
// p head
Node<E> q = p.getNext();
updateHead(h, (q != null) ? q : p);
}
return item;
}
//
p
Node<E> next = succ(p);
// p
if (next == null) {
//
updateHead(h, p);
break;
}
//
p = next;
}
return null;
}

CAS
null CAS
head

1.3

Java

1.3.1

19

1.3.2
ThreadPoolExecutor
new

ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime,

milliseconds,runnableTaskQueue, handler);

q corePoolSize

prestartAllCoreThreads

q runnableTaskQueue

1)

ArrayBlockingQueue FIFO

2)

LinkedBlockingQueue FIFO
ArrayBlockingQueue
Executors.newFixedThreadPool()

3)

SynchronousQueue
LinkedBlockingQueue
Executors.newCachedThreadPool

4)

PriorityBlockingQueue

5)

maximumPoolSize

6)

ThreadFactory

20

7)

RejectedExecutionHandler
AbortPolicy

1.3.3
JDK1.5 Java
q AbortPolicy
q CallerRunsPolicy
q DiscardOldestPolicy
q DiscardPolicy
RejectedExecutionHandler

q keepAliveTime

q TimeUnitDAYSHOURS
MINUTES(MILLISECONDS)(MICROSECONDS, )
(NANOSECONDS, )

1.3.4
execute execute
execute Runnable
threadsPool.execute(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
}
}); 

submit

future, future

future get get


21

get(long timeout, TimeUnit unit)


Future<Object> future = executor.submit(harReturnValuetask);
try {
Object s = future.get();
} catch (InterruptedException e) {
//
} catch (ExecutionException e) {
//
} finally {
//
executor.shutdown();
} 

1.3.5
shutdown shutdownNow
interrupt
shutdownNow STOP
shutdown
SHUTDOWN
isShutdown true
, isTerminaed true
shutdown
shutdownNow 

1.3.6
1-6

22


1-6

1)

2)

3)


 

public void execute(Runnable command) {


if (command == null)
throw new NullPointerException();
//
if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {
//
if (runState == RUNNING && workQueue.offer(command)) {
if (runState != RUNNING || poolSize == 0)
ensureQueuedTaskHandled(command);
}
//

23

else if (!addIfUnderMaximumPoolSize(command))
// RejectedExecutionException
reject(command); // is shutdown or saturated
}
}

: WorkerWorker
Worker run
public void run() {
try {
Runnable task = firstTask;
firstTask = null;
while (task != null || (task = getTask()) != null) {
runTask(task);
task = null;
}
} finally {
workerDone(this);
}
}

1.3.7

q CPU IO
q
q
q
CPU
Ncpu+1 IO
2*Ncpu CPU
IO

Runtime.getRuntime().availableProcessors() CPU
PriorityBlockingQueue

24

SQL
CPU CPU

SQL

 

1.3.8

taskCount

completedTaskCount taskCount

largestPoolSize

getPoolSize:

getActiveCount

beforeExecuteafterExecute
terminated

protected void beforeExecute(Thread t, Runnable r) { }

25

1.4

Java
Java Java7

1.4.1
BlockingQueue

1)

2)

1-2 :
1-1

add(e)

offer(e)

put(e)

offer(e,time,unit)

remove()

poll()

take()

poll(time,unit)

element()

peek()

q IllegalStateException("Queue full")
NoSuchElementException
q true
null
q put
take

2 put take
toffer poll o
26

put offer
offer true


1.4.2 Java
JDK7 7
1)

ArrayBlockingQueue

2)

LinkedBlockingQueue

3)

PriorityBlockingQueue

4)

DelayQueue

5)

SynchronousQueue

6)

LinkedTransferQueue

7)

LinkedBlockingDeque

1.4.3 ArrayBlockingQueue 
ArrayBlockingQueue FIFO

ArrayBlockingQueue fairQueue = new

ArrayBlockingQueue(1000,true);

public ArrayBlockingQueue(int capacity, boolean fair) {


if (capacity <= 0)
throw new IllegalArgumentException();
this.items = new Object[capacity];
lock = new ReentrantLock(fair);
notEmpty = lock.newCondition();
notFull =

lock.newCondition();

27

1.4.4 LinkedBlockingQueue 
LinkedBlockingQueue
Integer.MAX_VALUE

1.4.5 PriorityBlockingQueue 
PriorityBlockingQueue
compareTo PriorityBlockingQueue
Comparator

1.4.6 DelayQueue 
DelayQueue PriorityQueue
Delayed

DelayQueue DelayQueue
q

DelayQueue
DelayQueue DelayQueue

DelayQueue
DelayQueue TimerQueue DelayQueue

1.

Delayed
DelayQueue Delayed ScheduledThreadPoolExecutor

ScheduledFutureTask
time sequenceNumber

28

private static final AtomicLong sequencer = new AtomicLong(0);

ScheduledFutureTask(Runnable r, V result, long ns, long period) {


super(r, result);
this.time = ns;
this.period = period;
this.sequenceNumber = sequencer.getAndIncrement();
}

getDelay

public long getDelay(TimeUnit unit) {


return unit.convert(time - now(), TimeUnit.NANOSECONDS);
}

ns
getDelay
time getDelay
compareTo

public int compareTo(Delayed other) {


if (other == this) // compare zero ONLY if same object
return 0;
if (other instanceof ScheduledFutureTask) {
ScheduledFutureTask<?> x = (ScheduledFutureTask<?>)other;
long diff = time - x.time;
if (diff < 0)
return -1;
else if (diff > 0)
return 1;
else if (sequenceNumber < x.sequenceNumber)
return -1;
else
return 1;
}
long d = (getDelay(TimeUnit.NANOSECONDS) other.getDelay(TimeUnit.NANOSECONDS));
return (d == 0) ? 0 : ((d < 0) ? -1 : 1);
}


29

2.

long delay = first.getDelay(TimeUnit.NANOSECONDS);


if (delay <= 0)
return q.poll();
else if (leader != null)
available.await();
else {
Thread thisThread = Thread.currentThread();
leader = thisThread;
try {
available.awaitNanos(delay);
} finally {
if (leader == thisThread)
leader = null;
}
}

leader leader
await leader
leader awaitNanos delay

1.4.7 SynchronousQueue 
SynchronousQueue put take

SynchronousQueue true
public SynchronousQueue(boolean fair) {
transferer = fair ? new TransferQueue() : new TransferStack();
}

SynchronousQueue
SynchronousQueue
LinkedBlockingQueue ArrayBlockingQueue
30

1.4.8 LinkedTransferQueue 
LinkedTransferQueue TransferQueue
LinkedTransferQueue tryTransfer transfer
transfer take()
poll()transfer transfer
transfer tail
transfer
Node pred = tryAppend(s, haveData);
return awaitMatch(s, pred, e, (how == TIMED), nanos);

s tail CPU
CPU Thread.yield()

tryTransfer
false transfer tryTransfer
transfer
tryTransfer(E e, long timeout, TimeUnit unit)

false true


1.4.9 LinkedBlockingDeque 
LinkedBlockingDeque

LinkedBlockingDeque addFirstaddLastofferFirst
offerLastpeekFirstpeekLast First peek
Last
31

add addLast remove removeFirst take


takeFirst Jdk bug First Last
LinkedBlockingDeque

1.4.10

JDK

JDK
ArrayBlockingQueue Condition
private final Condition notFull;
private final Condition notEmpty;

public ArrayBlockingQueue(int capacity, boolean fair) {


//
notEmpty = lock.newCondition();
notFull =

lock.newCondition();

public void put(E e) throws InterruptedException {


checkNotNull(e);
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == items.length)
notFull.await();
insert(e);
} finally {
lock.unlock();
}
}

public E take() throws InterruptedException {


final ReentrantLock lock = this.lock;
lock.lockInterruptibly();

32

try {
while (count == 0)
notEmpty.await();
return extract();
} finally {
lock.unlock();
}
}

private void insert(E x) {


items[putIndex] = x;
putIndex = inc(putIndex);
++count;
notEmpty.signal();
}

LockSupport.park(this)

public final void await() throws InterruptedException {


if (Thread.interrupted())
throw new InterruptedException();
Node node = addConditionWaiter();
int savedState = fullyRelease(node);
int interruptMode = 0;
while (!isOnSyncQueue(node)) {
LockSupport.park(this);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
}
if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
interruptMode = REINTERRUPT;
if (node.nextWaiter != null) // clean up if cancelled
unlinkCancelledWaiters();
if (interruptMode != 0)
reportInterruptAfterWait(interruptMode);
} 

setBlocker unsafe.park

public static void park(Object blocker) {


Thread t = Thread.currentThread();
setBlocker(t, blocker);

33

unsafe.park(false, 0L);
setBlocker(t, null);
} 

unsafe.park native
public native void park(boolean isAbsolute, long time); 

park
1)

park unpark unpark


park

2)

3)

time

4)

JVM park park


Linux pthread_cond_wait JVM
src/os/linux/vm/os_linux.cpp os::PlatformEvent::park
void os::PlatformEvent::park() {
int v ;
for (;;) {
v = _Event ;
if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
}
guarantee (v >= 0, "invariant") ;
if (v == 0) {
// Do this the hard way by blocking ...
int status = pthread_mutex_lock(_mutex);
assert_status(status == 0, status, "mutex_lock");
guarantee (_nParked == 0, "invariant") ;
++ _nParked ;
while (_Event < 0) {
status = pthread_cond_wait(_cond, _mutex);
// for some reason, under 2.7 lwp_cond_wait() may return ETIME ...
// Treat this the same as if the wait was interrupted
if (status == ETIME) { status = EINTR; }
assert_status(status == 0 || status == EINTR, status, "cond_wait");
}
-- _nParked ;

// In theory we could move the ST of 0 into _Event past the unlock(),

34

// but then we'd need a MEMBAR after the ST.


_Event = 0 ;
status = pthread_mutex_unlock(_mutex);
assert_status(status == 0, status, "mutex_unlock");
}
guarantee (_Event >= 0, "invariant") ;
}
}

pthread_cond_wait cond condition

_cond_mutex unpark linux pthread_cond_signal park


windows WaitForSingleObject pthread_cond_wait
glibc-2.5 nptl/sysdeps/pthread/pthread_cond_wait.c
WAITING (parking) jstack dump

"main" prio=5 tid=0x00007fc83c000000 nid=0x10164e000 waiting on condition [0x000000010164d000]


java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for

<0x0000000140559fe8> (a

java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSy
nchronizer.java:2043)
at java.util.concurrent.ArrayBlockingQueue.put(ArrayBlockingQueue.java:324)
at blockingqueue.ArrayBlockingQueueTest.main(ArrayBlockingQueueTest.java:11)

1.5

Fork/Join

1.5.1 Fork/Join
Fork/Join Java7

Fork Join Fork/Join Fork


Join
35

1+2+10000 10 1
10 Fork/Join 1-7


1-7

1.5.2


work-stealing

1-8 

36


1-8

A
A


37

1.5.3 Fork/Join
Fork/Join
Fork/Join Fork/Join
1

fork

Fork/Join
1)

ForkJoinTask ForkJoin ForkJoin


fork() join() ForkJoinTask
Fork/Join

2)

RecursiveAction

RecursiveTask

ForkJoinPool ForkJoinTask ForkJoinPool

1.5.4 ForkJoin
ForkJoin 1+2+3+4
ForkJoin
2 4 ForkJoin
fork 1+2 3+4 join
RecursiveTask
package fj;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;

38

import java.util.concurrent.RecursiveTask;

public class CountTask extends RecursiveTask<Integer> {

private static final int THRESHOLD = 2;//


private int start;
private int end;

public CountTask(int start, int end) {


this.start = start;
this.end = end;
}

@Override
protected Integer compute() {
int sum = 0;

//
boolean canCompute = (end - start) <= THRESHOLD;
if (canCompute) {
for (int i = start; i <= end; i++) {
sum += i;
}
} else {
//
int middle = (start + end) / 2;
CountTask leftTask = new CountTask(start, middle);
CountTask rightTask = new CountTask(middle + 1, end);
//
leftTask.fork();
rightTask.fork();
//
int leftResult=leftTask.join();
int rightResult=rightTask.join();
//
sum = leftResult

+ rightResult;

}
return sum;
}

public static void main(String[] args) {


ForkJoinPool forkJoinPool = new ForkJoinPool();
// 1+2+3+4

39

CountTask task = new CountTask(1, 4);


//
Future<Integer> result = forkJoinPool.submit(task);
try {
System.out.println(result.get());
} catch (InterruptedException e) {
} catch (ExecutionException e) {
}
}

ForkJoinTaskForkJoinTask
compute
fork compute

join

1.5.5 Fork/Join
ForkJoinTask
ForkJoinTask isCompletedAbnormally()
ForkJoinTask getException
if(task.isCompletedAbnormally())
{
System.out.println(task.getException());
}

getException Throwable CancellationException


null

1.5.6 Fork/Join
ForkJoinPool ForkJoinTask ForkJoinWorkerThread ForkJoinTask
40

ForkJoinPool ForkJoinWorkerThread
ForkJoinTask fork ForkJoinTask fork
ForkJoinWorkerThread pushTask
public final ForkJoinTask<V> fork() {
((ForkJoinWorkerThread) Thread.currentThread())
.pushTask(this);
return this;
}

pushTask ForkJoinTask queue ForkJoinPool


signalWork()
final void pushTask(ForkJoinTask<?> t) {
ForkJoinTask<?>[] q; int s, m;
if ((q = queue) != null) {

// ignore if queue removed

long u = (((s = queueTop) & (m = q.length - 1)) << ASHIFT) + ABASE;


UNSAFE.putOrderedObject(q, u, t);
queueTop = s + 1;

// or use putOrderedInt

if ((s -= queueBase) <= 2)


pool.signalWork();
else if (s == m)
growQueue();
}
}

ForkJoinTask join Join


ForkJoinTask join
public final V join() {
if (doJoin() != NORMAL)
return reportResult();
else
return getRawResult();
}
private V reportResult() {
int s; Throwable ex;
if ((s = status) == CANCELLED)
throw new CancellationException();
if (s == EXCEPTIONAL && (ex = getThrowableException()) != null)
UNSAFE.throwException(ex);
return getRawResult();
}

41

doJoin() doJoin()
NORMALCANCELLEDSIGNAL
EXCEPTIONAL
q

CancellationException

doJoin()
private int doJoin() {
Thread t; ForkJoinWorkerThread w; int s; boolean completed;
if ((t = Thread.currentThread()) instanceof ForkJoinWorkerThread) {
if ((s = status) < 0)
return s;
if ((w = (ForkJoinWorkerThread)t).unpushTask(this)) {
try {
completed = exec();
} catch (Throwable rex) {
return setExceptionalCompletion(rex);
}
if (completed)
return setCompletion(NORMAL);
}
return w.joinTask(this);
}
else
return externalAwaitDone();
}

doJoin()

NORMAL EXCEPTIONAL

1.6

Java

42

Java
Java JVM
CPU Java JVM CPU
Java

1.7 Volatile
synchronized Volatile Volatile
synchronized
synchronized
Inter Volatile
Volatile

1.7.1
1-2

memory barriers

cache line

atomic operations

cache line fill

L1L2L3

cache hit

write hit

43

write misses the cache

1.7.2 Volatile
Java volatile java
Java
volatile volatilejava

1.7.3 Volatile
Volatile synchronized

1.7.4Volatile
Volatile x86 JIT
Volatile CPU
Java
instance = new Singleton();//instance volatile

0x01a3de1d: movb $00,01104800(%esi);0x01a3de24:

lock

addl $00,(%esp);

volatile IA-32
lock
1)
2) CPU

L1,L2 Volatile
44

JVM Lock

IA-32

Lock Lock
LOCK# LOCK#

CPU
LOCK
8.1.4 Intel486 Pentium
LOCK# P6
LOCK#

IA-32 Intel 64
MESI
IA-32 Intel 64

Pentium P6 family

1.7.5Volatile
Java Doug lea JDK7
LinkedTransferQueue Volatile

45

/** head of the queue */


private transient final PaddedAtomicReference<QNode> head;

/** tail of the queue */


private transient final PaddedAtomicReference<QNode> tail;

static final class PaddedAtomicReference <T> extends AtomicReference <T> {

// enough padding for 64bytes with 4byte refs


Object p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa, pb, pc, pd, pe;

PaddedAtomicReference(T r) {

super(r);

public class AtomicReference <V> implements java.io.Serializable {

private volatile V value;

//


LinkedTransferQueue
Headtail PaddedAtomicReference AtomicReference
64 4
15 60 Value 64 64
i7 Atom NetBurst Core Solo
Pentium M L1L2 L3 64
64

46

Doug lea 64

Volatile 64
64 P6 L1 L2
32

1.8 Synchronized
Synchronized
Java SE1.6 Synchronized
Java SE1.6

1.8.1
Java
q
q Class
q Synchonized

1.8.2
JVM JVM Monitor
monitorenter monitorexit
JVM
monitorenter monitorexit
47

JVM monitorenter monitorexit


monitor monitor monitorenter
monitor

1.8.3 Java
Java 3 Word
2 32 32bit
1-2
1-3

32/64bit

Mark Word

hashCode

32/64bit

Class Metadata Address

32/32bit

Array length

Java Mark Word HashCode32 JVM


Mark Word 1-3
1-4

25 bit

4bit

1bit

2bit

hashCode

01

Mark Word Mark Word


4 1-4
1-5
25 bit

23bit

4bit

2bit

48

1bit

2bit

00

10

GC

11

ID

Epoch

01

64 Mark Word 64bit 1-5


1-6

25bit

31bit

unused

ThreadID(54bit)

1bit

4bit

1bit

2bit

cms_free

01

01

hashCode

Epoch(2bit)

1.8.4
Java SE1.6
Java SE1.6

1.8.5
Hotspot

ID
CAS Mark Word
49

Mark Word
1 CAS
CAS

Mark Word
1
2

50

1-9

Java 6 Java 7
JVM -XXBiasedLockingStartupDelay = 0
JVM
-XX:-UseBiasedLocking=false

51

1.8.6
JVM

Mark Word Displaced Mark Word


CAS Mark Word

CAS Displaced Mark Word

52

1-10

CPU

1.8.7
1-7

CPU

CPU

1.8.8 6
HotSpot markOop.hpp biasedLocking.cpp
ObjectMonitor.cpp BasicLock.cpp

1.9

atomicatomic operation


Inter Java

1.9.1
1-8
53

Cache line

Compare and Swap

CAS

CPU

CPU pipeline

CPU CPU 5~6


X86 5~6
CPU
CPU

Memory order violation

CPU
CPU CPU

1.9.2
32 IA-32

1.9.3

6 16/32/64

54

1.9.4

i++

i=1, i++ 3 2

1-11

i
CPU1
CPU2
LOCK
,

55

1.9.5

CPU

L1L2 L3
6
LOCK
LOCK

1 CPU1 i CPU2 i


cache line
Inter486 ,

Inter LOCK
BTSBTRBTC XADDCMPXCHG
ADDOR

1.9.6Java
Java CAS

1.9.7 CAS
JVM CAS CMPXCHG
56

CAS CAS CAS


safeCount count
private AtomicInteger atomicI = new AtomicInteger(0);

private int i = 0;

public static void main(String[] args) {

final Counter cas = new Counter();

List<Thread> ts = new ArrayList<Thread>(600);

long start = System.currentTimeMillis();

for (int j = 0; j < 100; j++) {

Thread t = new Thread(new Runnable() {

@Override

public void run() {

for (int i = 0; i < 10000; i++) {

cas.count();

cas.safeCount();

});

ts.add(t);

for (Thread t : ts) {

t.start();

57

//

for (Thread t : ts) {

try {

t.join();

} catch (InterruptedException e) {

e.printStackTrace();

System.out.println(cas.i);

System.out.println(cas.atomicI.get());

System.out.println(System.currentTimeMillis() - start);

/**

* CAS

*/

private void safeCount() {

for (;;) {

int i = atomicI.get();

boolean suc = atomicI.compareAndSet(i, ++i);

if (suc) {

break;

58

/**

*/

private void count() {

i++;

Java1.5 JDK AtomicBoolean


boolean AtomicInteger int AtomicLong
long 1
1
Java CAS
LinkedTransferQueue Xfer CAS CAS
ABA
ABA CAS
A B A CAS
ABA
ABA 1A-2B3A Java1.5
JDK atomic AtomicStampedReference ABA
compareAndSet

public boolean compareAndSet(


V

expectedReference,//

59

newReference,//

int

expectedStamp, //

int

newStamp //

CAS CPU
JVM pause pause
de-pipeline, CPU

memory order violation CPU CPU pipeline flush CPU

CAS
CAS

i2,j=a ij=2a CAS ij Java1.5 JDK


AtomicReference CAS

1.9.8
JVM
JVM CAS
CAS
CAS

1.10
VolatileSynchronized Java
Volatile

60

You might also like