+ All Categories
Home > Documents > Principles of Software Construction

Principles of Software Construction

Date post: 20-Feb-2022
Category:
Upload: others
View: 4 times
Download: 0 times
Share this document with a friend
33
1 15-214 School of Computer Science Principles of Software Construction: Concurrency, Pt. 3 – java.util.concurrent Josh Bloch Charlie Garrod
Transcript
Page 1: Principles of Software Construction

115-214

SchoolofComputerScience

PrinciplesofSoftwareConstruction:Concurrency,Pt.3– java.util.concurrent

JoshBloch CharlieGarrod

Page 2: Principles of Software Construction

215-214

Administrivia

• Homework5bdueTuesday11:59p.m.– TurninyourworkbyWednesday9a.m.tobeconsideredasaBestFramework

Page 3: Principles of Software Construction

315-214

Canyoufindthebug?Publicserviceannouncement(1/1)/* From Linux 2.3.99 drivers/block/radi5.c */ static struct buffer_head * get_free_buffer(

struct stripe_head *sh, int b_size) {struct buffer_head *bh; unsigned long flags;

save_flags(flags);cli();if ((bh = sh->buffer_pool) == NULL)

return NULL;sh->buffer_pool = bh->b_next;bh->b_size = b_size; restore_flags(flags);return bh;

}

Page 4: Principles of Software Construction

415-214

Canyouwriteaprogramtofindthebug?Publicserviceannouncement(2/2)• TakeProgramAnalysis(17-355)andlearn(e.g):– Abstractinterpretation,atheoryforreasoningaboutprogramsevenbeforeyouknowtheirinput

– Concolic testing,combinessymbolicexecutionwithrandomizedtestingtoexercisehard-to-reachcornercases

– Andmore:interprocedural analysis,control-flowanalysis,shapeanalysis,anddynamicanalysis

• Thenbuildawesometoolstofindbugs,verifysecurityproperties,andgeneratetests!

• Newcourse,Spring2017– T/Th 10:30inGHC4102Prof.JonathanAldrich

Page 5: Principles of Software Construction

515-214

KeyconceptsfromTuesday…• Neverusewaitoutsideofawhileloop!– Thinktwicebeforeusingitatall

• Neitheranunder- noranover-synchronizerbe– Under-synchronizationcausessafety(&liveness)failures– Over-synchronizationcausesliveness(&safety)failures

• TwothingsthatIshouldhavesaidTuesday…

Page 6: Principles of Software Construction

615-214

1.Doaslittleaspossibleinsynchronizedregions

• Getin,getdone,andgetout– Obtainlock– Examineshareddata– Transformasnecessary– Droplock

• Ifyoumustdosomethingslow,moveitoutsidesynchronizedregion

Page 7: Principles of Software Construction

715-214

2.Avoidingdeadlock

• Deadlockcausedbyacycleinwaits-forgraph– T1:synchronized(a){ synchronized(b){ … } }– T2:synchronized(b){ synchronized(a){ … } }

• Toavoidthesedeadlocks:–Whenthreadshavetoholdmultiplelocksatthesametime,allthreadsobtainlocksinsameorder

T1 T2b

a

Page 8: Principles of Software Construction

815-214

java.util.concurrent isBIG(1)

I. Atomicvars - java.util.concurrent.atomic– Supportvariousatomicread-modify-writeops

II. Executorframework– Tasks,futures,threadpools,completionservice,etc.

III. Locks- java.util.concurrent.locks– Read-writelocks,conditions,etc.

IV. Synchronizers– Semaphores,cyclicbarriers,countdownlatches,etc.

Page 9: Principles of Software Construction

915-214

java.util.concurrent isBIG(2)

V. Concurrentcollections– Sharedmaps,sets,lists

VI. DataExchangeCollections– Blockingqueues,deques,etc.

VII. Pre-packagedfunctionality-java.util.arrays– Parallelsort,parallelprefix

Page 10: Principles of Software Construction

1015-214

I.Overviewofjava.util.atomic• Atomic{Boolean,Integer,Long}

– Boxedprimitivesthatcanbeupdatedatomically• AtomicReference<T>

– Objectreferencethatcanbeupdatedatomically– CoolpatternforstatemachineAtomicReference<StateEnum>

• Atomic{Integer,Long,Reference}Array– Arraywhoseelementsmaybeupdatedatomically

• Atomic{Integer,Long,Reference}FieldUpdater– Reflection-basedutilityenablingatomicupdatestovolatilefields

• LongAdder, DoubleAdder– Highlyconcurrentsums

• LongAccumulator,DoubleAccumulator– Generalizationofadder toarbitraryfunctions(max,min,etc.)

Page 11: Principles of Software Construction

1115-214

AtomicInteger example(review)[EJItem66]public class SerialNumber {

private static AtomicLong nextSerialNumber = new AtomicLong();

public static long generateSerialNumber() {return nextSerialNumber.getAndIncrement();

}}

Page 12: Principles of Software Construction

1215-214

VI.ExecutorframeworkOverview

• Flexibleinterface-basedtaskexecutionfacility• Keyabstractions– Runnable,Callable<T> - kindsoftasks

• Executor – thingthatexecutestasks• Future<T> – apromisetogiveyouaT• Executorservice– Executor that– Letsyoumanagetermination– CanproduceFuture instances

Page 13: Principles of Software Construction

1315-214

Executors – yourone-stopshopforexecutorservices• Executors.newSingleThreadExecutor()– Asinglebackgroundthread

• newFixedThreadPool(int nThreads)– Afixednumberofbackgroundthreads

• Executors.newCachedThreadPool()– Growsinresponsetodemand

Page 14: Principles of Software Construction

1415-214

Averysimpleexecutorserviceexample

• Backgroundexecutiononalong-livedworkerthread– Tostarttheworkerthread:

ExecutorService executor = Executors.newSingleThreadExecutor();

– Tosubmitataskforexecution:executor.execute(runnable);

– Toterminategracefully:executor.shutdown(); // Allows tasks to finish

• BetterreplacementforourrunInBackground andWorkQueue examplesfrompreviouslectures.

Page 15: Principles of Software Construction

1515-214

Otherthingsyoucandowithanexecutorservice• Waitforatasktocomplete

Foo foo = executorSvc.submit(callable).get();

• Waitforanyorallofacollectionoftaskstocompleteinvoke{Any,All}(Collection<Callable<T>> tasks)

• RetrieveresultsastaskscompleteExecutorCompletionService

• ScheduletasksforexecutioninthefutureScheduledThreadPoolExecutor

• etc.,adinfinitum

Page 16: Principles of Software Construction

1615-214

ForkJoinPool:executorserviceforForkJoinTask instancesclass SumSqTask extends RecursiveAction {

final long[] a; final int lo, hi; long sum;SumSqTask(long[] array, int low, int high) {

a = array; lo = low; hi = high;}protected void compute() {

if (h - l < THRESHOLD) {for (int i = l; i < h; ++i)

sum += a[i] * a[i];} else {

int mid = (lo + hi) >>> 1;SumSqTask left = new SumSqTask(a, lo, mid);left.fork(); // pushes task SumSqTask right = new SumSqTask(a, mid, hi);right.compute();right.join(); // pops/runs or helps or waits sum = left.sum + right.sum;

}}

}

Page 17: Principles of Software Construction

1715-214

II.Overviewofj.u.c.locks (1)

• ReentrantReadWriteLock– Shared/Exclusivemodelockswithtonsofoptions• Fairnesspolicy• Lockdowngrading• Interruptionoflockacquisition• Conditionsupport• Instrumentation

• ReentrantLock– LikeJava'sintrinsiclocks– Butwithmorebellsandwhistles

Page 18: Principles of Software Construction

1815-214

Overviewofj.u.c.locks (2)

• Condition– wait/notify/notifyAllwithmultiplewaitsetsperobject

• AbstractQueuedSynchronizer– SkeletalimplementationoflocksrelyingonFIFOwaitqueue

• AbstractOwnableSynchronizer,AbstractQueuedLongSynchronizer– Moreskeletalimplementations

Page 19: Principles of Software Construction

1915-214

ReentrantReadWriteLock exampleDoesthislookvaguelyfamiliar?private final ReentrantReadWriteLock rwl =

new ReentrantReadWriteLock();

rwl.readLock().lock();try {

// Do stuff that requires read (shared) lock} finally {

rwl.readLock().unlock();}

rwl.writeLock().lock();try {

// Do stuff that requires write (exclusive) lock} finally {

rwl.writeLock().unlock();}

Page 20: Principles of Software Construction

2015-214

III.Overviewofsynchronizers

• CountDownLatch– Oneormorethreadstowaitforotherstocountdown

• CyclicBarrier– asetofthreadswaitforeachothertobeready

• Semaphore– Likealockwithamaximumnumberofholders(“permits”)

• Phaser – Cyclicbarrieronsteroids• AbstractQueuedSynchronizer – rollyourown!

Page 21: Principles of Software Construction

2115-214

CountDownLatch exampleConcurrenttimer[EJItem69]public static long time(Executor executor, int nThreads,

final Runnable action) throws InterruptedException {CountDownLatch ready = new CountDownLatch(nThreads);CountDownLatch start = new CountDownLatch(1);CountDownLatch done = new CountDownLatch(nThreads);for (int i = 0; i < nThreads; i++) {

executor.execute(() -> {ready.countDown(); // Tell timer we're readytry {

start.await(); // Wait till peers are readyaction.run();

} catch (InterruptedException e) {Thread.currentThread().interrupt();

} finally {done.countDown(); // Tell timer we're done

}});}ready.await(); // Wait for all workers to be readylong startNanos = System.nanoTime();start.countDown(); // And they're off!done.await(); // Wait for all workers to finishreturn System.nanoTime() - startNanos;

}

Page 22: Principles of Software Construction

2215-214

IV.ConcurrentCollections

• Providehighperformanceandscalability

Unsynchronized ConcurrentHashMap ConcurrentHashMapHashSet ConcurrentHashSetTreeMap ConcurrentSkipListMapTreeSet ConcurrentSkipListSet

Page 23: Principles of Software Construction

2315-214

Youcan’t excludeconcurrentactivityfromaconcurrentcollection• Thisworksforsynchronizedcollections…

Map<String, String> syncMap =Collections.synchronizedMap(new HashMap<>());

synchronized(syncMap) {if (!syncMap.containsKey("foo"))

syncMap.put("foo", "bar");}

• Butnot forconcurrentcollections– Theydotheirowninternalsynchronization– Neversynchronizeonaconcurrentcollection!

Page 24: Principles of Software Construction

2415-214

Concurrentcollectionshaveprepackagedread-modify-writemethods• V putIfAbsent(K key, V value)• boolean remove,(Object key, Object value)• V replace(K key, V value)• boolean replace(K key, V oldValue, V newValue)• V compute(K key, BiFunction<...> remappingFn);• V computeIfAbsent,(K key, Function<...> mappingFn)• V computeIfPresent,(K key, BiFunction<...> remapFn)• V merge(K key, V value, BiFunction<...> remapFn)

Page 25: Principles of Software Construction

2515-214

Concurrentcollectionexample:canonicalizing mapprivate static final ConcurrentMap<String, String> map =

new ConcurrentHashMap<String, String>();

// This implementation is OK, but could be betterpublic static String intern(String s) {

String previousValue = map.putIfAbsent(s, s);return previousValue ==

null ? s : previousValue;}

Page 26: Principles of Software Construction

2615-214

Anoptimizedcanonicalizing map[EJItem69]• ConcurrentHashMap optimizedforread– Socallget first,putIfAbsent onlyifnecessary

// Good, fast implementation! public static String intern(String s) {

String result = map.get(s);if (result == null) {

result = map.putIfAbsent(s, s);if (result == null)

result = s;}return result;

}

Page 27: Principles of Software Construction

2715-214

ConcurrentobserverpatternrequiresopencallsThiscodeispronetolivenessandsafetyfailures!private final List<SetObserver<E>> observers =

new ArrayList<SetObserver<E>>();public void addObserver(SetObserver<E> observer) {

synchronized(observers) { observers.add(observer); }}public boolean removeObserver(SetObserver<E> observer) {

synchronized(observers) { return observers.remove(observer); }}private void notifyElementAdded(E element) {

synchronized(observers) {for (SetObserver<E> observer : observers)

observer.notifyAdded(this, element); // Callback!}

}

Page 28: Principles of Software Construction

2815-214

Adecentsolution:snapshotiterationprivate void notifyElementAdded(E element) {

List<SetObserver<E>> snapshot = null;

synchronized(observers) {snapshot = new ArrayList<SetObserver<E>>(observers);

}

for (SetObserver<E> observer : snapshot) {observer.notifyAdded(this, element); // Open call

}}

Page 29: Principles of Software Construction

2915-214

Abettersolution:CopyOnWriteArrayList [EJItem67]private final List<SetObserver<E>> observers =

new CopyOnWriteArrayList<SetObserver<E>>();

public void addObserver(SetObserver<E> observer) {observers.add(observer);

}public boolean removeObserver(SetObserver<E> observer) {

return observers.remove(observer);}private void notifyElementAdded(E element) {

for (SetObserver<E> observer : observers)observer.notifyAdded(this, element);

}

Page 30: Principles of Software Construction

3015-214

V.DataexchangecollectionssummaryHoldelementsforprocessingbyanotherthread• BlockingQueue – Supportsblockingops– ArrayBlockingQueue,LinkedBlockingQueue– PriorityBlockingQueue,DelayQueue– SynchronousQueue

• BlockingDeque – Supportsblockingops– LinkedBlockingDeque

• TransferQueue – BlockingQueue inwhichproducersmaywaitforconsumerstoreceiveelements– LinkedTransferQueue

Page 31: Principles of Software Construction

3115-214

SummaryofBlockingQueuemethods

Throwsexception Specialvalue Blocks Timesout

Insert add(e) offer(e) put(e) offer(e, time, unit)

Remove remove() poll() take() poll(time, unit)

Examine element() peek() n/a n/a

Page 32: Principles of Software Construction

3215-214

SummaryofBlockingDequemethods• Firstelement(head)methods

• Lastelement(tail)methods

Throws exception Specialvalue Blocks Timesout

Insert addFirst(e) offerFirst(e) putFirst(e) offerFirst(e,time, unit)

Remove removeFirst() pollFirst() takeFirst() pollFirst(time,unit)Examine getFirst() peekFirst() n/a n/a

Throws exception Specialvalue Blocks Timesout

Insert addLast(e) offerLast(e) putLast(e) offerLast(e,time, unit)

Remove removeLast() pollLast() takeLast() pollLast(time,unit)

Examine getLast() peekLast() n/a n/a

Page 33: Principles of Software Construction

3315-214

Summary

• java.util.concurrent isbigandcomplex• Butit’swelldesignedandengineered– Easytodosimplethings– Possibletodocomplexthings

• ExecutorframeworkdoesforexecutionwhatCollectionsframeworkdidforaggregation

• Thistalkjustscratchedthesurface– Butyouknowthelayofthelandandthejavadoc isgood

• Alwaysbettertousej.u.c thantorollyourown!


Recommended