Formations Langages & Algo

Logo Java 8 - Concurrency Performance

Formation Java 8 - Concurrency Performance

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

Durée 3 jours • Prix (HT) 2250€

Logo OfficielleOfficielle
Logo ExclusiveExclusive
Logo CertifianteProgramme

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!