·±…¥µ…‡ Java Concurrency

download ·±…¥µ…‡ Java Concurrency

If you can't read please download the document

  • date post

    19-Aug-2014
  • Category

    Documents

  • view

    122
  • download

    8

Embed Size (px)

Transcript of ·±…¥µ…‡ Java Concurrency

Java Concurrency (1) : J.U.CGuice Guice java.util.concurrent(J.U.C) Java Java Java

1 2

J.U.C J.U.C

API

3

J.U.C

J.U.C

J.U.C MindManger

API MindManger 8

J.U.C

MindManger API

Java Concurrency (2):Atomic Atomic java.util.concurrent

part 1Queue Queue

Java +1/-1 - Doug Lea

++i

--i

JSR 166 Java

backport-util-concurrent synchronized

public final synchronized void set(int newValue); public final synchronized int getAndSet(int newValue); public final synchronized int incrementAndGet(); volatile synchronized volatile JNI get() Java

JSR 166 CPU API

backport-util-concurrent

JDK 5.0

java.util.concurrent.atomic.AtomicInteger int addAndGet(int delta) i =i+delta boolean compareAndSet(int expect, int update) == false true

int decrementAndGet() 1 int get() --i

int getAndAdd(int delta) t=i;i+=delta;return t; int getAndDecrement() 1 int getAndIncrement() 1 int getAndSet(int newValue) t=i;i=newValue;return t; int incrementAndGet() 1 void lazySet(int newValue) set() volatile volatile ++i i++ i--

void set(int newValue) i=newValue boolean weakCompareAndSet(int expect, int update) == happen-before weakCompareAndSet weakCompareAndSet Java compareAndSet happen-before JSR unsafe.compareAndSwapInt() JSR

package xylz.study.concurrency.atomic; import java.util.concurrent.atomic.AtomicInteger; import org.junit.Test; importstatic org.junit.Assert.*; publicclass AtomicIntegerTest { @Test publicvoid testAll() throws InterruptedException{ final AtomicInteger value = new AtomicInteger(10); assertEquals(value.compareAndSet(1, 2), false); assertEquals(value.get(), 10); assertTrue(value.compareAndSet(10, 3)); assertEquals(value.get(), 3); value.set(0); // assertEquals(value.incrementAndGet(), 1); assertEquals(value.getAndAdd(2),1); assertEquals(value.getAndSet(5),3); assertEquals(value.get(),5); // finalint threadSize = 10; Thread[] ts = new Thread[threadSize]; for (int i = 0; i < threadSize; i++) { ts[i] = new Thread() { publicvoid run() { value.incrementAndGet(); } }; } // for(Thread t:ts) {

t.start(); } for(Thread t:ts) { t.join(); } // assertEquals(value.get(), 5+threadSize); } }

AtomicInteger

AtomicLong AtomicBoolean AtomicReference

(1)http://stackoverflow.com/questions/2443239/java-atomicinteger-what-are-thedifferences-between-compareandset-and-weakcompar (2)http://stackoverflow.com/questions/1468007/atomicinteger-lazyset-and-set

Java Concurrency (3):

part 2

AtomicIntegerArray/AtomicLongArray/AtomicReferenceArray AtomicIntegerArray int get(int i) i IndexOutOfBoundsException API AtomicInteger

API

void set(int i, int newValue) void lazySet(int i, int newValue) int getAndSet(int i, int newValue) boolean compareAndSet(int i, int expect, int update) boolean weakCompareAndSet(int i, int expect, int update) int getAndIncrement(int i) int getAndDecrement(int i) int getAndAdd(int i, int delta) int incrementAndGet(int i) int decrementAndGet(int i) int addAndGet(int i, int delta) API

AtomicIntegerFieldUpdater/AtomicLongFieldUpdater/AtomicRef erenceFieldUpdater API 1 volatile volatile volatile

2

public/protected/default/private

3 4 volatile 5 int/long AtomicReferenceFieldUpdater AtomicIntegerFieldUpdater final final

static final

AtomicLongFieldUpdater

Integer/Long

package xylz.study.concurrency.atomic; import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; publicclass AtomicIntegerFieldUpdaterDemo { class DemoData{ publicvolatileint value1 = 1; volatileint value2 = 2; protectedvolatileint value3 = 3; privatevolatileint value4 = 4; } AtomicIntegerFieldUpdater getUpdater(String fieldName) { return AtomicIntegerFieldUpdater.newUpdater(DemoData.class, fieldName); } void doit() { DemoData data = new DemoData(); System.out.println("1 ==> "+getUpdater("value1").getAndSet(data, 10)); System.out.println("3 ==> "+getUpdater("value2").incrementAndGet(data)); System.out.println("2 ==> "+getUpdater("value3").decrementAndGet(data)); System.out.println("true ==> "+getUpdater("value4").compareAndSet(data, 4, 5)); } publicstaticvoid main(String[] args) {

AtomicIntegerFieldUpdaterDemo demo = new AtomicIntegerFieldUpdaterDemo(); demo.doit(); } }

DemoData

value3/value4

AtomicIntegerFieldUpdaterDemo

AtomicMarkableReference Object Boolean Object/Boolean AtomicStampedReference AtomicMarkableReference AtomicStampedReference

AtomicInteger Object ABA ABA

AtomicMarkableReference/AtomicStampedReference

Java Concurrency (4): happens-before

part 3

Java Concurrency in Practice

Java

JVM

JVM CPU

CPU

CPU

CPU

package xylz.study.concurrency.atomic; publicclass ReorderingDemo { staticint x = 0, y = 0, a = 0, b = 0; publicstaticvoid main(String[] args) throws Exception {

for (int i = 0; i < 100; i++) { x=y=a=b=0; Thread one = new Thread() { publicvoid run() { a = 1; x = b; } }; Thread two = new Thread() { publicvoid run() { b = 1; y = a; } }; one.start(); two.start(); one.join(); two.join(); System.out.println(x + " " + y); } } }

one/two 1) 10 11 00 run()

x,y,a,b JVM run() 0,0 CPU

100 00 CPU JVM

(0

a=1;x=b;b=1;y=a; x=0 1 a 0 a=1 y=a one one a=1 two

CPU

Happens-beforeJava A/B happens-before Action Java start() join() Action happens-before A/B JMM B happens-before Java Memeory Model A

happens-before 1 2 3 volatile Action happens-before Action

happens-before happens-before happens-before happens-before Thread.isAlive()==false A A B A B B interrupt isInterrupted happens-before interrupted() finalizer B happens-before C A

4 Thread.start() 5 Thread Thread.join 6 B 7 8 A A

happens-before happens-before C B

happens-before

volatilevolatile volatile synchronized volatile volatile volatile volatile synchronized

1

Java

valatile

volatile

2 volatile volatile volatile happens-before valatile volatile volatile volatile

CPU

volatile

volatile volatileboolean done = false; while( ! done ){ dosomething(); } volatile 1 2 3

1 2

Java Concurrency in Practice Volatile

Java Concurrency (5):JDK 5 Java synchronized

part 4

1 2 3

volatile

volatile

synchronized

CASCAS CAS V 3 V B V Compare and Swap A B A

nonblocking algorithms

CPU compareAndSet() AtomicInteger private volatile int value; volatile

public final int get() { return value; } ++i public final int incrementAndGet() { for (;;) { int current = get(); int next = current + 1; if (compareAndSet(current, next)) return next; } } CAS +1 CAS

compareAndSet

JNI

CPU

public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); } CPU CAS JNI Java

J.U.C

CAS

synchronized CAS

J.U.C

CAS CAS

ABA

one two CAS A B

V two one

A V one

two A CAS one

A

AtomicStampedReference/AtomicMarkableReference

1 2

Java Concurrency (6):

part 1

synchronized JDK 5 JDK 5

JDK 5 JNI

java.util.concurrent.locks.Lock

java.util.concurrent.locks.ReadWriteLock java.util.concurrent.locks.Lock void lock(); API

void lockInterruptibly() throws InterruptedException;

y y

y y InterruptedException Condition newCondition();

Lock

Condition

Condition

boolean tryLock();

true

false

boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

true

y y

y true

y y InterruptedException false time 0

void unlock(); lock() tryLock() tryLock(xx) lockInterruptibly() unlock() API AtomicInteger

package xylz.study.concurrency.lock; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class AtomicIntegerWithLock { private int value; private Lock lock = new ReentrantLock(); public AtomicIntegerWithLock() { super(); } public AtomicIntegerWithLock(int value) { this.value = value; } public final int get() { lock.lock(); try { return value; } finally { lock.unlock(); } } public final void set(int newValue) { lock.lock(); try { value = newValue; } finally { lock.unlock(); } } public final int getAndSet(int newValue) { lock.lock(); try {

int ret = value; value = newValue; return ret; } finally { lock.unlock(); } } public final boolean compareAndSet(int expect, int update) { lock.lock(); try { if (value == expect) { value = update; return true; } return false; } finally { lock.unlock(); } } public final int getAndIncrement() { lock.lock(); try { return value++; } finally { lock.unlock(); } } public final int getAndDecrement() { lock.lock(); try { return value--; } finally { lock.unlock();

} } public final int incrementAndGet() { lock.lock(); try { return ++value; } finally { lock.unlock(); } } public final int decrementAndGet() { lock.lock(); try { return --value; } finally { lock.unlock(); } } public String toString() { return Integer.toString(get()); } } AtomicIntegerWithLock lock/unlock Lock lock() unlock lock() unlock() finally unlock Lock ++/--

java.util.concurrent.locks.ReentrantLock.ReentrantLock Lock synchronized Lock Lock

public static void main(String[] args) throws Exception{ final int max = 10; final int loopCount = 100000; long costTime = 0; for (int m = 0; m < max; m++) { long start1 = System.nanoTime(); final AtomicIntegerWithLock value1 = new AtomicIntegerWithLock(0); Thread[] ts = new Thread[max