Formation Java 8 - Concurrency Performance

Tout ce que vous avez toujours voulu savoir sur la concurrence sans oser le demander

Formation officielle
Formation officielle
Exclusivité Zenika
Exclusivité Zenika

Durée 3 jours
Prix(HT) : 2250 €
XJ-CONC-J8-03

Prochaines sessions

26 mars 2018
Xavier Detant
Paris

Description

The "Extreme Java - Concurrency Performance for Java 8" course is the most intense learning experience you will ever get. It is aimed at the busy Java professional who would like to learn essential information about core Java topics. Each of the sections has been thoroughly researched by the author, Dr Heinz Kabutz, famous in 135 countries for his invention of "The Java Specialists' Newsletter".


Throughout the course we use the new Java 8 syntax for lambdas and streams, in order to make the code more readable. Not only will you learn about threading, performance, compare-and-swap non-blocking constructs, garbage collectors and so many other topics that you can apply in your work, but at the same time you will get familiar with Java 8. In addition, we also cover all the relevant constructs that we find in Java 8, such as StampedLock, LongAdder, parallel streams and many others.


In our outline below, we show you all that we will cover during our training. You will get an opportunity to try out what you learn with carefully thought out exercises. These will help you to really understand what is going on.


Objectifs

  • Learn how to truly understand Java concurrency

Pré-requis : 

  • Preferably a formal qualification in computer science or related field
  • At least two years of professional Java programming

Public : 

  • Développeur

Pédagogie : 

40% théorie 60% pratique

Programme

Introduction

  • Welcome To The Course
  • How we deal with questions
  • Exercises with partial solutions
  • Certificate of Training
  • History of concurrency
  • New supercomputers
  • Moore's Law
  • Hardware impact of concurrency
  • Benefits of threads
  • Programming is easier
  • Better throughput
  • Simpler modeling
  • Risks of threads
  • Safety vs liveness
  • Safety hazards
  • Using basic synchronized
  • Caching of fields
  • Code reordering
  • Annotations for Concurrency
  • Class annotations
  • Field annotations
  • Threads are everywhere
  • Threads created by JVM
  • Threads created by frameworks
  • Timer
  • Servlets and JavaServer Pages
  • Remote Method Invocation (RMI)
  • Short Java 7 and 8 Primer
  • Underscores in integral literals
  • Generic type inference
  • Lambdas
  • Method References
  • Streams
  • Primitive Streams

Thread Safety

  • Introduction to Thread Safety
  • Synchronization and shared data
  • Your program has latent defects
  • Atomicity
  • Byte code generated by simple count++
  • Demonstration of broken servlet
  • Compound actions
  • Check-then-act
  • Read-write-modify
  • Sharing Objects
  • Visibility
  • Synchronization and visibility
  • Reason why changes are not visible
  • Making fields visible with volatile
  • Volatile flushing
  • Thread confinement
  • Unshared objects are safe
  • Ad-hoc thread confinement
  • ThreadLocal
  • Stack confinement
  • Immutability
  • Immutable is always thread safe
  • Definition of immutable
  • Final fields
  • Designing a thread-safe class
  • Encapsulation
  • Primitive vs object fields
  • Thread-safe counter with invariant
  • Post-conditions
  • Pre-condition
  • Waiting for pre-condition to become true

Building Blocks

  • Synchronized collections
  • Old Java 1.0 thread-safe containers
  • Synchronized wrapper classes
  • Locking with compound actions
  • Concurrent collections
  • Scalability
  • ConcurrentHashMap
  • Class annotations
  • Additional atomic operations
  • Java 8 ConcurrentHashMap
  • CopyOnWriteCollections
  • Blocking queues and the producer-consumer pattern
  • How BlockingQueues work
  • Java implementations of BlockingQueue
  • ArrayBlockingQueue
  • Circular array lists
  • LinkedBlockingQueue
  • PriorityBlockingQueue
  • DelayQueue
  • SynchronousQueue
  • TransferQueue
  • Deques
  • ArrayDeque
  • LinkedBlockingDeque
  • ConcurrentLinkedDeque (Java 7)
  • Work stealing
  • Good defaults for collections
  • Synchronizers
  • CountDownLatch
  • FutureTask
  • Semaphore
  • CyclicBarrier
  • Phaser (Java 7)

Task Execution

  • The Executor framework
  • Executor interface
  • Motivation for using Executor
  • Decoupling task submission from execution
  • Execution policies
  • Who will execute it?
  • In which order? (FIFO, LIFO, by priority)
  • Various sizing options for number of threads and queue length
  • Thread pool structure
  • Thread pool benefits
  • Memory leaks with ThreadLocal
  • Standard ExecutorService configurations
  • ThreadPoolExecutor
  • Executor lifecycle, state machine
  • Shutdown() vs ShutdownNow()
  • Finding exploitable parallelism
  • Breaking up a single client request
  • Sequential vs parallel
  • Callable and Future
  • Callable controlling lifecycle
  • Example showing page renderer with future
  • Limitations of parallelizing heterogeneous tasks
  • CompletionService
  • Time limited tasks
  • Using Parallel Streams (Java 8)
  • Transforming collections into streams
  • Limitations of using parallel streams for IO
  • Finding prime numbers in parallel
  • Filtering and mapping streams
  • Configuring underlying Fork/Join framework

Cancellation

  • Cancellation
  • Reasons for wanting to cancel a task
  • Cooperative vs preemptive cancellation
  • Using flags to signal cancellation
  • Cancellation policies
  • Interruption
  • Origins of interruptions
  • How does interrupt work?
  • Policies in dealing with InterruptedException
  • Thread.interrupted() method
  • Responding to interruption
  • Letting the method throw the exception
  • Restoring the interrupt and exiting
  • Ignoring the interrupt status
  • Saving the interrupt for later
  • Non-interruptible blocking
  • Reactions of IO libraries to interrupts
  • Interrupting locks

Thread Pools

  • Homogenous, independent and thread-agnostic tasks
  • Sizing thread pools
  • Danger of hardcoding worker number
  • Problems when pool is too large or small
  • Formula for calculating how many threads to use
  • CPU-intensiv vs IO-intensive task sizing
  • Examples of various pool sizes
  • Mixing different types of tasks
  • Determining the maximum allowed threads on your operating system
  • Configuring ThreadPoolExecutor
  • corePoolSize
  • maximumPoolSize
  • keepAliveTime
  • Using default Executors.new* methods
  • Managing queued tasks
  • PriorityBlockingQueue
  • Saturation policies
  • Abort
  • Caller runs
  • Discard
  • Discard oldest
  • Thread factories
  • Customizing thread pool executor after construction

Fork/Join

  • Basics
  • Breaking up work into chunks
  • ForkJoinPool and ForkJoinTask
  • Work-stealing in ForkJoinPool
  • ForkJoinTask state machine
  • RecursiveTask vs RecursiveAction
  • Example of a parallel recursive function
  • Parallel Fibonacci Calculator
  • Fork/Join vs. Compute
  • Parallel merge sort
  • Sorting in Java 8
  • Managing tasks
  • Canceling a task
  • Visibility guarantees with fork/join
  • Use cases of fork/join
  • Using new parallel streams in Java 8 to simplify code

Avoiding Liveness Hazards

  • Deadlock
  • The drinking philosophers
  • Causing a deadlock amongst philosophers
  • Resolving deadlocks
  • Discovering deadlocks
  • Lock-ordering deadlocks
  • Defining a global ordering
  • Dynamic lock order deadlocks
  • Defining order on dynamic locks
  • Checking whether locks are held
  • Imposing a natural order
  • Deadlock between cooperating objects
  • Open calls and alien methods
  • Example of a parallel recursive function
  • Example in Vector
  • Resource deadlocks
  • Avoiding and Diagnosing
  • Avoiding multiple locks
  • Using open calls
  • Unit testing for lock ordering deadlocks
  • Adding a sleep to cause deadlocks
  • Verifying thread deadlocks
  • Deadlock analysis with thread dumps
  • Livelock
  • Causes
  • How to detect

Testing Concurrent Programs

  • Testing for correctness
  • Checking for data races
  • Automatic tooling
  • JChord
  • JavaRaceFinder
  • FindBugs
  • IntelliJ IDEA
  • False positives
  • Memory requirements of automatic tools
  • Testing through bulk updates
  • Server HotSpot interference
  • Testing pitfalls
  • Controlling HotSpot and JIT
  • Turning off optimizations
  • Randomizing bulk operations
  • Testing field visibility
  • Single updates, with time delays
  • Pros and cons of various approaches
  • Examples of testing broken code
  • Testing for deadlocks
  • Testing for performance
  • HotSpot tricks
  • Loop unrolling
  • Useless code elimination
  • Inlining of method calls
  • Lock eliding
  • Lock coarsening
  • Eliminating object creation
  • HotSpot interference in microbenchmarks
  • HotSpot method call threshold
  • HotSpot compile time
  • Getting the fastest most optimized code
  • Randomization
  • Ensuring HotSpot does not overoptimize
  • Math.random() vs ThreadLocalRandom
  • Cost of remainder calculation
  • Statistics
  • Average and variance
  • Value of the minimum
  • Excluding warmup results
  • Eliminating interference
  • Length of timings
  • Value of including standard deviation
  • Concurrent performance Testing
  • Difference between single and multi-threaded test
  • ArrayList vs CopyOnWriteArrayList iteration benchmark
  • Context switching cost interference

Performance and Scalability

  • Thinking about performance
  • Effects of serial sections and locking
  • Performance vs scalability
  • How fast vs how much
  • Mistakes in traditional performance optimizations
  • 2-tier vs multi-tier
  • Evaluating performance tradeoffs
  • Amdahl's and Little's laws
  • Formula for Amdahl's Law
  • Utilization according to Amdahl
  • Maximum useful cores
  • Problems with Amdahl's law in practice
  • Formula for Little's Law
  • Applying Little's Law in practice
  • How threading relates to Little's Law
  • Costs introduced by threads
  • Context switching
  • Cache invalidation
  • Locking and unlocking
  • Memory barriers
  • Escape analysis and uncontended locks
  • Lock elision
  • Reducing lock contention
  • Exclusive locks
  • Safety first!
  • Narrowing lock scope
  • Using ConcurrentHashMap
  • Performance comparisons
  • Reducing lock granularity
  • Lock splitting
  • Using CopyOnWrite collections
  • Lock striping
  • In ConcurrentHashMap
  • In ConcurrentLinkedQueue
  • Avoiding 'hot fields'
  • ReadWriteLock
  • Immutable objects
  • Atomic fields
  • How to monitor CPU utilization
  • Reasons why CPUs might not be loaded
  • How to find 'hot locks'
  • Hotspot options for lock performance

Explicit Locks

  • Lock and ReentrantLock
  • Memory visibility semantics
  • ReentrantLock implementation
  • Using the explicit lock
  • Using try-finally
  • tryLock and timed locks
  • Using try-lock to avoid deadlocks
  • Interruptible locking
  • Performance considerations
  • Java 5 vs Java 6 performance
  • Throughput on contended locks
  • Uncontended performance
  • Heavily contended locks
  • Synchronized vs ReentrantLock
  • Memory semantics
  • Ease of use
  • Prefer synchronized
  • Read-write locks
  • ReadWriteLock interface
  • Understanding system to avoid starvation
  • ReadWriteLock implementation options
  • Release preference
  • Reader barging
  • Reentrancy
  • Downgrading
  • Upgrading
  • StampedLock (Java 8)
  • Difference between StampedLock and ReentrantReadWriteLock
  • Pessimistic reading and writing
  • Optimistic reading
  • Conditional changes by upgrading read to write lock
  • Performance differences between StampedLock and ReentrantReadWriteLock

Building Custom Synchronizers

  • Managing state dependence
  • Single-threaded vs multi-threaded
  • Structure of blocking state-dependent actions
  • Example using bounded queues
  • Introducing condition queues
  • With intrinsic locks
  • Using condition queues
  • State-dependence
  • Condition predicate
  • Lock
  • Condition queue
  • Waking up too soon
  • Waiting for a specific timeout
  • Conditional waits
  • Missed signals
  • InterruptedException
  • notify() vs notifyAll()
  • Encapsulating condition queues
  • Explicit condition objects
  • Condition interface
  • Benefits of explicit condition queues
  • Timed conditions

Atomic Variables and Nonblocking Synchronization

  • Disadvantages of locking
  • Elimination of uncontended intrinsic locks
  • Volatile vs locking performance
  • Priority inversion
  • Hardware support
  • Optimistic locking
  • Compare-and-Swap (CAS)
  • Compare-and-Set
  • Managing conflicts with CAS
  • Simulation of CAS
  • Nonblocking counter
  • CAS support in the JVM
  • Shared cache lines
  • Performance advantage of padding
  • Using @sun.misc.Contended (Java 8)
  • Atomic variable classes
  • Optimistic locking classes
  • Very fast when not too much contention
  • Types of atomic classes
  • How do atomics work?
  • Atomic array classes
  • LongAdder and LongAccumulator (Java 8)
  • Performance comparisons: Locks vs atomics
  • Cost of atomic spin loops
  • Nonblocking algorithms
  • Scalability problems with lock-based algorithms
  • Definition of nonblocking and lock-free
  • Nonblocking stack
  • Doing speculative work

Performance

  • Java Memory
  • Garbage Collection
  • Generational Spaces
  • Difference between young and old GC
  • Stop-The-World events
  • Throughput Collector (Parallel)
  • How it works
  • Tuning the throughput collector
  • Concurrent Mark Sweep Collector
  • Various phases either STW or Concurrent
  • Types of serious STW failures
  • Concurrent Mode Failure
  • Promotion Failed
  • Perm/Meta GC
  • Tuning the throughput collector
  • G1 Collector
  • How it works
  • Tuning the G1 collector
  • Sizing the collector
  • Total Heap
  • New/Old
  • Eden/Survivor
  • Tenuring threshold
  • Working example in tuning a large Fibonacci number calculation
  • Measuring GC Activity
  • Flags for generating GC logs
  • Understanding GC information
  • References
  • Reference Objects
  • Object Reachability
  • Using References
  • SoftReference
  • WeakReference
  • PhantomReference
  • Java Optimizations
  • Tuning Process
  • Optimization Techniques - Big Gains Quickly
  • Specifying the required performance
  • Optimization methodology
  • System Overview - 'The Box'
  • Analyzing CPU bottlenecks
  • Microbenchmarking
  • Java Microbenchmarking Harness (JMH)
  • JIT and HotSpot
  • Just-in-Time
  • HotSpot
  • Client
  • Server
  • Tiered Compilation
  • VM Switches
  • Effects on performance and benchmarking
  • Typical Problem Areas
  • Object Creation
  • Array creation
  • Temporary objects
  • Lazy initialization
  • Strings
  • intern
  • StringBuilder vs StringBuffer vs String
  • char[] creation with modifying methods
  • += complexity
  • String appending performance
  • Parsing Strings
  • substring() in various versions of Java
  • String deduplication (Java 8)
  • Regular Expressions
  • Exception performance
  • Loops
  • Tuning loops
  • Extracting invariants
  • Method calls
  • Arrays and loops
  • Cache lines
  • Calls to JNI
  • Benchmarking
  • Other Areas
  • Final
  • Conclusion
  • Tips on where to learn more
  • Thank you!