Въведение в java.util.concurrent

41
Михаил Стойнов & Красимир Семерджиев

description

Въведение в java.util.concurrent. Михаил Стойнов & Красимир Семерджиев. Agenda. Hardware evolution - free lunch is over Java concurrency before Java SE 5 Atomic operations Java.util.concurrent overview Java SE5 vs. Java SE6. Hardware evolution. - PowerPoint PPT Presentation

Transcript of Въведение в java.util.concurrent

Page 1: Въведение в  java.util.concurrent

Михаил Стойнов &

Красимир Семерджиев

Page 2: Въведение в  java.util.concurrent

Hardware evolution - free lunch is over Java concurrency before Java SE 5 Atomic operations Java.util.concurrent overview Java SE5 vs. Java SE6

Page 3: Въведение в  java.util.concurrent

?!?!?

Moore’s law for CPU clock speed is over

Intel talks about 100x core CPU

Next major revolution in software - concurrency

Majority of software is not ready for that

“There ain’t no such thing as a free lunch.” —R. A. Heinlein,

Page 4: Въведение в  java.util.concurrent

Availability – faster response time, maximize throughput, access DBs/backends

GUIs– autonomous objects, animation, concurrent events

Parallelism – utilizing CPUs, overlapping I/O, multiple clients

Protection – isolating different activities,

Page 5: Въведение в  java.util.concurrent

Hard to implement!

Higher resource usage

Need to start decomposing tasks

Deal with safety and isolation

Page 6: Въведение в  java.util.concurrent

System(VM) = Objects + Activities(Threads) Activities touch/change objects’ state Every called method should eventually

execute as soon as possible Liveness and safety not enforced by

compilers

Java Virtual Machine

Page 7: Въведение в  java.util.concurrent

Every object has a lock Every Class has a lock (being an Object) Acquiring locks works through

“synchronized” blocks/methods Can “temporarily release” the lock by

calling wait() or wait(ms) Can wake up waiting threads by calling

notify() or notifyAll() Synchronized blocks control atomicity

Object

method

lock

method

method

Page 8: Въведение в  java.util.concurrent

Objects represent a state and procedures over it

Every Thread represents the state of a single activity touching different objects

Synchronized block ensures thread-local cache flush/reload

Volatile keyword ensures per-variable cache flush/reload

Page 9: Въведение в  java.util.concurrent

Stateless objects – comprise mainly of methods

Immutable objects – state never changes after creation

Atomic objects – legal-to-legal state changes only

Locking – exclusive access on state change

Page 10: Въведение в  java.util.concurrent

Make sure that a user always sees a legal state (never sees a temporary state)

Make sure that you have only legal->legal transitions

Page 11: Въведение в  java.util.concurrent

Java doesn’t guarantee fairness Locks are reentrant Wrong order of acquiring nested monitors

leads to deadlock Once deadlocked – threads will hang forever On wait(ms) you dunno whether it was a

notify() call or timeout that happened Thread scheduling provides no guarantees Lock contention is a scalability blocker

Page 12: Въведение в  java.util.concurrent

CAS stands for Compare-and-Swap Atomic instruction at CPU level (cmpxchg,

load and reserve, store conditional, etc.). Since Java SE 5 – adopted in Java to

allowing concurrent structures to be implemented. Old

value

=?

Ignore Set it

Page 13: Въведение в  java.util.concurrent

Setting a reference to an existing object is an atomic operation

Object construction is not an atomic operation!

Page 14: Въведение в  java.util.concurrent

Too low level – hard to implement high level structures (like latch, rendezvous and barrier)

Can’t pass a lock between threads Can’t attach a lock to an Object while no

thread is working with it

Page 15: Въведение в  java.util.concurrent

Lock contention – too many threads/CPUs Multiple-request data changes Fine-grained locking Keeping a lock without wasting a thread

Page 16: Въведение в  java.util.concurrent

The java.util.concurrent package aims to do for concurrency what java.util.Collections did for data structures. It makes◦ Some problems go away◦ Some problems trivial to solve by everyone◦ Some problems easier to solve by concurrent programmers◦ Some problems possible to solve by experts

Whenever you are about to use... Object.wait, notify, notifyAll, synchronized, new

Thread(); Check first if there is a class that ...

◦ automates what you are trying to do, or ◦ would be a simpler starting point for your own solution

Page 17: Въведение в  java.util.concurrent

java.util.concurrent is based on over 3 years experience with edu.oswego.cs.dl.util.concurrent

Many refactorings and functionality improvements

Additional native/JVM support ◦ Timing, atomics, built-in monitor extensions

Page 18: Въведение в  java.util.concurrent

Executors, Thread pools, and Futures Queues and blocking queues Timing Locks and Conditions Synchronizers: Semaphores, Barriers, etc Atomic variables Miscellany

Page 19: Въведение в  java.util.concurrent

Flexibility at expense of verbositylock.lock();

try {

action();

}

finally {

lock.unlock();

}

Overcomes limitations of synchronized◦ Doesn’t force block structured locking/unlocking◦ Allow interruptible lock acquisition and “try lock”◦ Can define customized implementations◦ Fair/Unfair

Page 20: Въведение в  java.util.concurrent
Page 21: Въведение в  java.util.concurrent

interface Lock {

void lock();

void lockInterruptibly() throws IE;

boolean trylock();

boolean trylock(long timeout,

TimeUnit unit)throws IE;

void unlock();

Condition newCondition();

}

Concrete ReentrantLock implementation◦ Fast, scalable with synchronized block semantics,

and additional query methods◦ Also FairReentrantLock subclass with slower but

more predictable first-in-first-out arbitration

Page 22: Въведение в  java.util.concurrent

class ParticleUsingLock { private int x, y; private final Random rng = new Random();private final Lock lock = new ReentrantLock(); public void move() throws InterruptedException { lock.lockInterruptibly(); // allow cancellation try { x += rng.nextInt(3) - 1; y += rng.nextInt(3) – 1; } finally { lock.unlock(); } } public void draw(Graphics g) { int lx, ly; lock.lock(); // no interrupts – AWT Event Thread try { lx = x; ly = y; } finally { lock.unlock(); } g.drawRect(lx, ly, 10, 10); } }

Page 23: Въведение в  java.util.concurrent

interface ReadWriteLock { Lock readLock(); Lock writeLock();}

A pair of locks for enforcing multiple-reader, single-writer access◦ Each used in the same way as ordinary locks

Concrete ReentrantReadWriteLock◦ Almost always the best choice for apps◦ Each lock acts like a reentrant lock

Page 24: Въведение в  java.util.concurrent

Remember Lock.newCondition(); ? Condition factors out the Object monitor

methods (wait, notify and notifyAll)◦ into distinct objects to give the effect of having

multiple wait-sets per object◦ can combine them with the use of arbitrary Lock

implementations. Where a Lock replaces the use of synchronized methods and statements, a Condition replaces the use of the Object monitor methods.

Page 25: Въведение в  java.util.concurrent

interface Condition {

void await() throws IE;

void awaitUninterruptibly();

long awaitNanos(long nanos) throws IE;

boolean awaitUntil(Date deadline) throws IE;

void signal();

void signalAll();

}

Allows more than one wait condition per object◦ Even for built-in locks, via Locks utility class

Allows much simpler implementation of some classic concurrent designs

Page 26: Въведение в  java.util.concurrent

Example

Page 27: Въведение в  java.util.concurrent

A small collection of small classes that:◦ Provide good solutions to common special-

purpose synchronization problems◦ Provide better ways of thinking about designs

But worse ways when they don't naturally apply!

◦ Can be tricky or tedious to write yourself Semaphore CountDownLatch CyclicBarrier

Page 28: Въведение в  java.util.concurrent

Semaphores can be seen as permit holders◦ Create with initial number of permits ◦ acquire takes a permit, waiting if necessary◦ release adds a permit◦ But no actual permits change hands.◦ Semaphore just maintains the current count.

Can use for both “locking” and “synchronizing”◦ With initial permits=1, can serve as a lock◦ Useful in buffers, resource controllers◦ Use in designs prone to missed signals ◦ Semaphores “remember” past signals

Page 29: Въведение в  java.util.concurrent

A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.

A CountDownLatch is initialized with a given count

The await methods block until the current count reaches zero due to invocations of the countDown method, after which all waiting threads are released and any subsequent invocations of await return immediately. This is a one-shot phenomenon -- the count cannot be reset.

Page 30: Въведение в  java.util.concurrent

class Driver { // ... void main(int N) throws InterruptedException { final CountDownLatch startSignal = new CountDownLatch(1); final CountDownLatch doneSignal = new CountDownLatch(N); for (int i = 0; i < N; ++i) // Make threads new Thread() { public void run() { try { startSignal.wait(); doWork(); doneSignal.countDown(); } catch(InterruptedException ie) {} }}.start(); initialize(); startSignal.countDown(); // Let all threads proceed doSomethingElse(); doneSignal.await(); // Wait for all to complete cleanup(); }}

Page 31: Въведение в  java.util.concurrent

Example

Page 32: Въведение в  java.util.concurrent

j.u.c.atomic contains classes representing scalars supporting "CAS“

boolean compareAndSet(expectedV, newV)◦ Atomically set to newV if holding expectedV◦ Always used in a loop

Essential for writing efficient code on MPs◦ Nonblocking data structures, optimistic algorithms,

reducing overhead and contention when updates center on a single field

JVMs use best construct available on platform◦ Compare-and-swap, Load-linked/Store-conditional, Locks

j.u.c.a also supplies reflection-based classes that allow CAS on given volatile fields of other classes

Page 33: Въведение в  java.util.concurrent

class Random { // snippets private AtomicLong seed; Random(long s) { seed = new AtomicLong(s); } long next(){ for(;;) { long s = seed.get(); long nexts = s * ... + ...; if (seed.compareAndSet(s,nexts) return s; } } }

Faster and less contention in programs with a single Random accessed by many threads

Let’s see java.util.Random

Page 34: Въведение в  java.util.concurrent

There’s also an AtomicReference class Why not use that to create a non-blocking

stack? The idea is the same:

◦ The push() method observes the current top node◦ constructs a new node to be pushed on the stack◦ if the topmost node has not changed since

the initial observation, installs the new node◦ If the CAS fails, it means that another thread

has modified the stack, so the process starts again

Page 35: Въведение в  java.util.concurrent

Example

Page 36: Въведение в  java.util.concurrent

The Segments◦ The maps is split into segments, only they lock

The root link Retries before resorting to locking – size()

Page 37: Въведение в  java.util.concurrent

Basic debugging support is added (in jconsole and thread dumps) to detect deadlocks based on java.util.concurrent structures

Double-ended deques added

Page 38: Въведение в  java.util.concurrent

Looking at thread dump (Ctrl+Break)◦ Locked monitors are noted◦ Monitors to wait for are shown◦ Owned synchronizers are listed◦ Java-level (synchronized) deadlocks are auto

detected

Page 39: Въведение в  java.util.concurrent

These slides are for educational purpose only

In most of the cases synchronized blocks are sufficient!

Synchronized blocks modes is intentionally kept simple

java.util.concurrent is hard to debug and needlessly complex for simple scenarios!

Do not use java.util.concurrent except if you really HAVE to!

Page 40: Въведение в  java.util.concurrent

Three short articles from Brian Goetz:http://www-128.ibm.com/developerworks/java/library/j-jtp04186/http://www-128.ibm.com/developerworks/java/library/j-jtp11234/http://www-128.ibm.com/developerworks/java/library/j-jtp10264/

Page 41: Въведение в  java.util.concurrent

For further questions:Михаил Стойнов[email protected]/blogКрасимир Семерджиев[email protected] Java Users Groupjava-bg.orggroups.google.com/group/bg-jug