Modern Java Concurrency
Upcoming SlideShare
Loading in...5

Like this? Share it with your network


Modern Java Concurrency

Uploaded on

A unique take on modern Java concurrency.

A unique take on modern Java concurrency.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
  • Concurrency, java, threads
    Are you sure you want to
    Your message goes here
No Downloads


Total Views
On Slideshare
From Embeds
Number of Embeds



Embeds 15 11 4

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

    No notes for slide
  • \n
  • \n
  • \n
  • * Everyone hands up (& repeat)\n* OK, put your hand down if the primary VM you use at work is version 5 or lower\n* Version 4?\n
  • * Hands up if you’re daunted by the refactoring that would be required\n\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • * It’s a little-known fact that Otters are scared of log-linear graphs\n
  • \n
  • * So you can contort more and more, but you’re chasing diminishing returns\n* Ultimately, that exponent gap between clock speed and memory will do for you\n
  • * Raise your hand if you use the process monitor on Ubuntu or another Linux. OK, have you seen how Java processes behave under that?\n
  • * Raise your hand if you know why we use the keyword “synchronized” to denote a critical section in Java\n
  • \n
  • * Hands up if you know what a NUMA architecture is?\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • * Let’s step through a quasi-realistic example\n
  • \n
  • \n
  • \n
  • \n
  • * So this is pretty much a statement of the state-of-the-art in Java concurrency\n
  • * But let’s step back - and talk about concurrency in general, rather than just in the context of Java\n
  • \n
  • \n
  • \n
  • \n


  • 1. Modern JavaConcurrencyBen Evans @kittlyst @java7developer Slide Design by Kerry Kenneally
  • 2. Who is this guy anyway? 2
  • 3. Who is this guy anyway? 3
  • 4. Modern Java concurrency• Not a new subject• Underwent a revolution with Java 5• More refinements since (and still more coming in 7)• j.u.c really fast in 6 (and better yet in 7)• However, still under-appreciated by a surprising number• Too much Java 4-style concurrency code still in PROD• Why...? 4
  • 5. Java concurrency - Why not upgrade?• Too much legacy code - people scared to refactor?• People don’t know java.util.concurrent is easier than “classic” Java concurrency?• People don’t know j.u.c is faster than classic?• People don’t know that you can mix-and-match (with a bit of care)?• Still not being taught at Universities?• Not enough people reading Doug Lea or Brian Goetz? 5
  • 6. Modern Java concurrency• My take: Previous treatments haven’t involved enough otters.• I will rectify this.• If you suffer from lutraphobia, you may want to leave now... 6
  • 7. Otterly Amazing Tails of Modern Java Concurrency• Srsly.• Otters! 7
  • 8. Why Otters?• Otters are a very good metaphor for concurrency• Not just because they look a bit like threads (ie long and thin)• Collaborative• Competitive• Sneaky• Can hare off in opposite directions• Capable of wreaking havoc if not contained 8
  • 9. Some History• Until recently, most computers had only one processing core• Multithreading was simulated on a single core• Not true concurrency• Serial approach to algorithms often sufficed• Interleaved multithreading can mask errors• Or be more forgiving than true concurrency• Why and how (and when) did things change? 9
  • 10. Moore’s Law• “The number of transistors on an economic-to- produce chip roughly doubles every 2 years”• Originally stated in 1965 (and expected to hold for the 10 years to 1975) - but still going strong• Named for Gordon Moore (Intel founder)• About transistor counts• Not clock speed• Or overall performance 10
  • 11. Transistor Counts 11
  • 12. Moore’s Law - Problems• Very successful within own frame of reference, but• Not about overall performance• Memory latency exponent gap• Need to keep the processing pipeline full• Add memory caches of faster SRAM “close” to the CPU (L1, L2 etc)• Modern code (after JIT compilation) usually restricted by L1 processor cache misses rather than CPU speed 12
  • 13. Spending the transistor budget More and more complex contortions... ILP, CMT, Branch prediction, etc, etc 13
  • 14. Multi-core• If we can’t increase clock speed / overall perf, have to go multi- core• Concurrency and performance are tied together• Real concurrency - separate threads can execute on different cores at the same moment• The JVM runtime controls scheduling• Java thread scheduling does NOT behave like OS scheduling• Concurrency becomes the main way to squeeze out more performance 14
  • 15. Classic Concurrency synchronized (this) { // do some stuff }• Provides exclusion• Need locking to make mutation concurrency-safe• Locking gets complicated• Can become fragile• Why “synchronized” ? 15
  • 16. The JMM• Mathematical description of memory• Most impenetrable part of the Java language spec• JMM makes • Primary concepts – synchronizes-with minimum guarantees – happens-before – release-before-acquire• Real JVMs (and – as-if-serial CPUs) may do more • happens-before defines a “partial order” (if you’re a mathematician) 16
  • 17. Synchronizes-with• Threads have their own description of an object’s (mutable) state• Periodically, this must be flushed to main memory and other threads• “synchronized” means that this local view has been synchronized-with the other threads• Defines touch-points where threads must perform synching• Compare with NUMA Architectures 17
  • 18. java.util.concurrent• Thanks, Doug!• j.u.c has building blocks for concurrent code – ReentrantLock – Condition – ConcurrentHashMap – CopyOnWriteArrayList – Other Concurrent Data Structures 18
  • 19. Locks and Conditions in j.u.c private final Lock lock= new ReentrantLock(); lock.lock(); try { • Lock is an interface // do some stuff } finally { • ReentrantLock is usual lock.unlock(); implementation } • Condition takes the place of wait() / notify() 19
  • 20. ConcurrentHashMap• HashMap has: – Hash function – Even distribution of buckets• Concurrent form – Can lock independently – Seems lock-free to users – Has atomic operations• Basically drop-in replacement 20
  • 21. CopyOnWriteArrayList• Similar to CHM• Not quite a drop-in replacement• Iterator will never throw ConcurrentModificationException• Makes separate copies of underlying structure 21
  • 22. CountDownLatch• A group consensus construct• 2 methods - countDown() and await() – countDown() decrements the count – await() blocks until the count reaches zero (i.e. consensus)• Ctor takes an int param - the count• Quite a few use cases• Especially multithreaded testing 22
  • 23. Handoff Queue (in-mem)• Efficient way to hand off work between threads (or threadpools)• BlockingQueue is often a good choice• Offers several different ways to interact with it (see Javadoc)• Blocking operations with timeouts can be very useful (eg for backoff / retry)• Two basic impls - ArrayList and LinkedList backed• Java 7 introduces the shiny new TransferQueue 23
  • 24. Executors• j.u.c execution constructs - Callable, Future, FutureTask• In addition to the venerable Thread and Runnable• Stop using TimerTask!• The Executors class provides lots of helpful factory methods for making threadpools• ScheduledThreadPoolExecutor is one standard choice (but there are others)• The final building block for making modern concurrent applications 24
  • 25. Example - ThreadPoolManagerprivate final ScheduledExecutorService stpe =Executors.newScheduledThreadPool(2);private final BlockingQueue<WorkUnit<String>> lbq;public ScheduledFuture<?> run(QueueReaderTask msgReader) { msgReader.setQueue(lbq); return stpe.scheduleAtFixedRate(msgReader, 10, 10,TimeUnit.MILLISECONDS);}public void cancel(final ScheduledFuture<?> handle) { stpe.schedule(new Runnable() { public void run() { handle.cancel(true); } }, 10, TimeUnit.MILLISECONDS);} 25 23
  • 26. Example - QueueReaderTaskpublic abstract class QueueReaderTask implements Runnable { private boolean shutdown = false; protected BlockingQueue<WorkUnit<String>> lbq; public void run() { while (!shutdown) { try { WorkUnit<String> wu = lbq.poll(10, TimeUnit.MILLISECONDS); if (wu != null) doAction(wu.getWork()); } catch (InterruptedException e) { shutdown = true; } } } public abstract void doAction(String msg); public void setQueue(BlockingQueue<WorkUnit<String>> q) { lbq = q; }} 26 23
  • 27. Fork/Join• Java 7 introduces F/J – similar to MapReduce – useful for a certain class of problems – F/J executions are not really threads• In our example, we subclass RecursiveAction• Need to provide a compute() method and a way of merging results• Framework provides an invokeAll() to hand off more tasks 27 28
  • 28. Fork/Join@Overrideprotected void compute() { if (size() < SMALL_ENOUGH) { System.arraycopy(updates, start, result, 0, size()); Arrays.sort(result, 0, size()); } else { int mid = size() / 2; BlogSorter left = new BlogSorter(updates, start, start + mid); BlogSorter right = new BlogSorter(updates, start + mid, end); invokeAll(left, right); merge(left, right); }} 28 29
  • 29. Fork/Joinprivate void merge(BlogSorter left, BlogSorter right) { int i = 0; int lCt = 0; int rCt = 0; while (lCt < left.size() && rCt < right.size()) { result[i++] = (left.result[lCt].compareTo(right.result[rCt]) < 0) ? left.result[lCt++] : right.result[rCt++]; } while (lCt < left.size()) result[i++] = left.result[lCt++]; while (rCt < right.size()) result[i++] = right.result[rCt++];}public int size() { return end - start; }public Update[] getResult() { return result; } 29 30
  • 30. Concurrent Java Code• Mutable state (objects) protected by locks• Concurrent data structures (CHM, COWAL)• Be careful of performance (esp COWAL)• Synchronous multithreading - explicit synchronization• Executor-based threadpools• Asynch multithreading communicates using queue-like handoffs 30
  • 31. Stepping Back• Concurrency is key to the future of performant code• Mutable state is hard• Need both synch & asynch state sharing• Locks can be hard to use correctly• JMM is a low-level, flexible model – Need higher-level concurrency model – Thread is still too low-level 31
  • 32. Imagine a world...• Collections were thread-safe by default• Objects were immutable by default• State was well encapsulated and not shared by default• The runtime helped out the programmer more• Thread wasn’t the default choice for unit of concurrent execution• Copy-on-write was the basis for mutation of collections / synchronous multithreading• Hand-off (via something queue-like) was the basis for asynchronous multithreading 32
  • 33. Wouldn’t it be nice?• Imagine all of that was built-in to the language syntax• But still built on top of the JVM• Still based on the JMM view of memory• What could such a language be?• One thing’s for sure - it’s not Java• We can’t fix Java now, but we can learn from it (both good and bad points• And we can dream... 33
  • 34. Acknowledgments• All otter images Creative Commons or Fair Use• Photos owned by Flickr Users: moff, spark, sodaro, lonecellotheory, tomsowerby, farnsworth, prince, marcus_jb1973, mliu92, Ed Zitron, NaturalLight & monkeywing• Dancing Otter by the amazing Nicola Slater @ folksy 34
  • 35. Thank You 35