Running on Java 24-ea+25-3155 (Preview)
Home of The JavaSpecialists' Newsletter

Extreme Java - Concurrency Performance Course

"Java Concurrency in Practice" and "Performance Tuning" combined as a 3-day intensive course.

Using Java 21

Duration of 3 Days


This course could be your most productive learning experience ever! It is aimed at the busy Java professional who wants to quickly learn and apply new essentials on core Java topics. All topics have been thoroughly researched by Dr Heinz Kabutz, famous in over 150 countries for his Java Specialists' Newsletter.

During the course you will learn about threading, performance, compare-and-swap non-blocking constructs, garbage collectors and many other topics that you will be able to quickly apply in your own work. We will also cover all relevant constructs found in Java 8, such as StampedLock, LongAdder, parallel streams and many more. We also cover Java 9 VarHandles. The course always uses the latest version of OpenJDK.

During the training, you will always get a chance to try out what you have learned in carefully thought out exercises. This will help you understand and quickly internalize what you have just learned.

Is this course for you?

Students who have successfully completed this course, can expect the following outcomes:

  1. Throughout the course, we use the latest Java syntax. The first outcome would thus be an understanding of how the new Java constructs work.
  2. Students gain a good understanding of why threads are important and what the risks are. They learn how to share objects safely, including visibility concerns. They also master safety techniques of thread confinement, stack confinement and object confinement. Through this, they learn how to design a thread-safe class.
  3. They will know the difference between a synchronized and a concurrent collection and when to use which one. This is particularly important to be able to write high-performance code that scales well.
  4. They would understand how a blocking queue can be used to build producer consumer systems and what the various blocking queues are in Java.
  5. They would know how Semaphore, CountDownLatch and Phaser works.
  6. Students would learn how to use the thread pool executors to run tasks asynchronously. They would also learn how to configure these, including how to cope with an unexpected number of tasks and how the various settings interact.
  7. They will learn how to break up a large tasks into smaller tasks by choosing good task boundaries, resulting in tasks that are homogeneous and independent.
  8. They would learn how to cleanly cancel tasks that have been started by using interruptions and volatile boolean fields.
  9. Students would learn how the Fork/Join Pool works by comparing it to a normal single-threaded recursive algorithm. They will also get an opportunity to refactor a piece of Fork/Join Code to use parallel streams instead, in order to see how Java 8 can make coding a bit easier.
  10. Students would know how to detect and solve liveness issues, such as deadlock, livelock and contention.
  11. They would also know how to find and solve performance bottlenecks, especially in threaded code.
  12. They would know how ReentrantLock, ReentrantReadWriteLock and the new Java 8 StampedLock work and how we can use that to write efficient code using optimistic techniques.
  13. They would know how to write their own synchronizers when needed, by creating state-dependent classes.
  14. Students would understand what atomic classes are and know techniques to use them to build efficient non-blocking classes that offer better performance under contention. They also learn how VarHandles can improve performance.
  15. They would understand the most common garbage collection algorithms: throughput, concurrent and G1 and also how to tune each one to give best performance.
  16. They would know how to discover performance bottlenecks in an application and also how to solve these. They would also learn how profilers can be used to find bottlenecks and the role of microbenchmarks in confirming these.
  17. Throughout the course, a strong emphasis is placed on the practical application of learning. Each student needs to complete a set of exercises to demonstrate that they have understood the material.

"The course is founded on the book 'Java Concurrency In Practice', which is obligatory reading for Java software specialists. But teams that need to arrive together at a common understanding of the advanced topic of Java concurrency will benefit both from the course's clear focus on the essential topics and from the practical exercises."
Marko Zarkovic, Canada

Extreme Java - Concurrency Performance Enquiry


Prerequisites

This course is ideally suited to the professional Java programmer with at least 2 years experience, who would like to learn how to truly understand Java concurrency.

Pricing Options

We have several options for you to join this course:

1. Virtual In-house Course:

Presented via video conference to your team of programmers by the author of the course. Price is €11475 for up to 10 students, above that is an additional €995 per student.

  • Example 1: Course with 8 students taught remotely via video conference, price is €11475. Price per student is €1434.
  • Example 2: Course with 12 students taught remotely via video conference, price is €13465. Price per student is €1122.
  • Example 3: Course with 24 students taught remotely via video conference, price is €25405. Price per student is €1058.

Please contact us if you have any questions.

2. In-person In-house Course:

Presented at your company in-person by one of our Certified JavaSpecialist Instructors. Price is €16900 for up to 10 students, above that is an additional €1690 per student, plus the travel expenses of the instructor. Note that for in-person in-house courses, we need a minimum of three consecutive training days.

  • Example 1: Course with 8 students taught on-site at your company, price is €16900. Price per student is €2112.
  • Example 2: Course with 12 students taught on-site at your company, price is €20280. Price per student is €1690.
  • Example 3: Course with 18 students taught on-site at your company, price is €30420. Price per student is €1690.

Please contact us if you have any questions.

2. Open Enrollment Classroom Course:

We occasionally offer this course as a classroom course in Chania on the Island of Crete. Price for the course is €3639 per student.

We also offer this course as an open enrollment live remote course that you can attend from anywhere. Price is €2470 per student.

Please contact us if you have would like to make a booking or if you have any questions.

4. Self-Paced Course:

This course is also available as a self-paced course.

Please contact us if you have any questions.

* Prices exclude EU VAT and withholding taxes where applicable. Please contact us for an exact quote for your country.

Open Courses

All our courses are offered as in-house courses. Please contact us on heinz@javaspecialists.eu.

* Price is excluding EU VAT where applicable. Please contact us for an exact quote for your country.

Detailed Outline

Extreme Java - Concurrency Performance
Extreme Java - Concurrency Performance
Imagemap
Day 11 IntroductionWelcome To The CourseHow we deal with questionsExercises with partial solutionsCertificate of TrainingHistory of concurrencyNew supercomputersMoore's LawHardware impact of concurrencyBenefits of threadsProgramming is easierBetter throughputSimpler modelingRisks of threadsSafety vs livenessSafety hazardsUsing basic synchronizedCaching of fieldsCode reorderingAnnotations for ConcurrencyClass annotationsField annotationsThreads are everywhereThreads created by JVMThreads created by frameworksTimerServlets and JavaServer PagesRemote Method Invocation (RMI)Short Java 7 and 8 PrimerUnderscores in integral literalsGeneric type inferenceLambdasMethod ReferencesStreamsPrimitive Streams2 Thread SafetyIntroduction to Thread SafetySynchronization and shared dataYour program has latent defectsAtomicityByte code generated by simple count++Demonstration of broken servletCompound actionsCheck-then-actRead-write-modifySharing ObjectsVisibilitySynchronization and visibilityReason why changes are not visibleMaking fields visible with volatileVolatile flushingThread confinementUnshared objects are safeAd-hoc thread confinementThreadLocalStack confinementImmutabilityImmutable is always thread safeDefinition of immutableFinal fieldsDesigning a thread-safe classEncapsulationPrimitive vs object fieldsThread-safe counter with invariantPost-conditionsPre-conditionWaiting for pre-condition to become true3 Building BlocksSynchronized collectionsOld Java 1.0 thread-safe containersSynchronized wrapper classesLocking with compound actionsConcurrent collectionsScalabilityConcurrentHashMapNew Java 8 methodsAdditional atomic operationsJava 8 ConcurrentHashMapCopyOnWriteCollectionsBlocking queues and the producer-consumer patternHow BlockingQueues workJava implementations of BlockingQueueArrayBlockingQueueCircular array listsLinkedBlockingQueuePriorityBlockingQueueDelayQueueSynchronousQueueTransferQueueDequesArrayDequeLinkedBlockingDequeConcurrentLinkedDeque (Java 7)Work stealingGood defaults for collectionsSynchronizersCountDownLatchFutureTaskSemaphoreCyclicBarrierPhaser (Java 7)4 Task ExecutionThe Executor frameworkExecutor interfaceMotivation for using ExecutorDecoupling task submission from executionExecution policiesWho will execute it?In which order? (FIFO, LIFO, by priority)Various sizing options for number of threads and queue lengthThread pool structureThread pool benefitsMemory leaks with ThreadLocalStandard ExecutorService configurationsThreadPoolExecutorExecutor lifecycle, state machineShutdown() vs ShutdownNow()Finding exploitable parallelismBreaking up a single client requestSequential vs parallelCallable and FutureCallable controlling lifecycleExample showing page renderer with futureLimitations of parallelizing heterogeneous tasksCompletionServiceTime limited tasksUsing Parallel Streams (Java 8)Transforming collections into streamsLimitations of using parallel streams for IOFinding prime numbers in parallelFiltering and mapping streamsConfiguring underlying Fork/Join framework5 CancellationCancellationReasons for wanting to cancel a taskCooperative vs preemptive cancellationUsing flags to signal cancellationCancellation policiesInterruptionOrigins of interruptionsHow does interrupt work?Policies in dealing with InterruptedExceptionThread.interrupted() methodResponding to interruptionLetting the method throw the exceptionRestoring the interrupt and exitingIgnoring the interrupt statusSaving the interrupt for laterNon-interruptible blockingReactions of IO libraries to interruptsInterrupting locksDay 26 Thread PoolsHomogenous, independent and thread-agnostic tasksSizing thread poolsDanger of hardcoding worker numberProblems when pool is too large or smallFormula for calculating how many threads to useCPU-intensiv vs IO-intensive task sizingExamples of various pool sizesMixing different types of tasksDetermining the maximum allowed threads on your operating systemConfiguring ThreadPoolExecutorcorePoolSizemaximumPoolSizekeepAliveTimeUsing default Executors.new* methodsManaging queued tasksPriorityBlockingQueueSaturation policiesAbortCaller runsDiscardDiscard oldestThread factoriesCustomizing thread pool executor after construction7 Fork/JoinBasicsBreaking up work into chunksForkJoinPool and ForkJoinTaskWork-stealing in ForkJoinPoolForkJoinTask state machineRecursiveTask vs RecursiveActionExample of a parallel recursive functionParallel Fibonacci CalculatorFork/Join vs. ComputeParallel merge sortSorting in Java 8Managing tasksCanceling a taskVisibility guarantees with fork/joinUse cases of fork/joinUsing new parallel streams in Java 8 to simplify code8 Avoiding Liveness HazardsDeadlockThe drinking philosophersCausing a deadlock amongst philosophersResolving deadlocksDiscovering deadlocksLock-ordering deadlocksDefining a global orderingDynamic lock order deadlocksDefining order on dynamic locksChecking whether locks are heldImposing a natural orderDeadlock between cooperating objectsOpen calls and alien methodsExample in VectorResource deadlocksAvoiding and DiagnosingAvoiding multiple locksUsing open callsUnit testing for lock ordering deadlocksAdding a sleep to cause deadlocksVerifying thread deadlocksDeadlock analysis with thread dumpsLivelockCausesHow to detect9 Testing Concurrent ProgramsTesting for correctnessChecking for data racesAutomatic toolingJChordJavaRaceFinderFindBugsIntelliJ IDEAFalse positivesMemory requirements of automatic toolsTesting through bulk updatesServer HotSpot interferenceTesting pitfallsControlling HotSpot and JITTurning off optimizationsRandomizing bulk operationsTesting field visibilitySingle updates, with time delaysPros and cons of various approachesExamples of testing broken codeTesting for deadlocksTesting for performanceHotSpot tricksLoop unrollingUseless code eliminationInlining of method callsLock elidingLock coarseningEliminating object creationHotSpot interference in microbenchmarksHotSpot method call thresholdHotSpot compile timeGetting the fastest most optimized codeRandomizationEnsuring HotSpot does not overoptimizeMath.random() vs ThreadLocalRandomCost of remainder calculationStatisticsAverage and varianceValue of the minimumExcluding warmup resultsEliminating interferenceLength of timingsValue of including standard deviationConcurrent performance TestingDifference between single and multi-threaded testArrayList vs CopyOnWriteArrayList iteration benchmarkContext switching cost interference10 Performance and ScalabilityThinking about performanceEffects of serial sections and lockingPerformance vs scalabilityHow fast vs how muchMistakes in traditional performance optimizations2-tier vs multi-tierEvaluating performance tradeoffsAmdahl's and Little's lawsFormula for Amdahl's LawUtilization according to AmdahlMaximum useful coresProblems with Amdahl's law in practiceFormula for Little's LawApplying Little's Law in practiceHow threading relates to Little's LawCosts introduced by threadsContext switchingCache invalidationLocking and unlockingMemory barriersEscape analysis and uncontended locksLock elisionReducing lock contentionExclusive locksSafety first!Narrowing lock scopeUsing ConcurrentHashMapPerformance comparisonsReducing lock granularityLock splittingUsing CopyOnWrite collectionsLock stripingIn ConcurrentHashMapIn ConcurrentLinkedQueueAvoiding "hot fields"ReadWriteLockImmutable objectsAtomic fieldsHow to monitor CPU utilizationReasons why CPUs might not be loadedHow to find "hot locks"Hotspot options for lock performance11 Explicit LocksLock and ReentrantLockMemory visibility semanticsReentrantLock implementationUsing the explicit lockUsing try-finallytryLock and timed locksUsing try-lock to avoid deadlocksInterruptible lockingPerformance considerationsJava 5 vs Java 6 performanceThroughput on contended locksUncontended performanceHeavily contended locksSynchronized vs ReentrantLockMemory semanticsEase of usePrefer synchronizedRead-write locksReadWriteLock interfaceUnderstanding system to avoid starvationReadWriteLock implementation optionsRelease preferenceReader bargingReentrancyDowngradingUpgradingStampedLock (Java 8)Difference between StampedLock and ReentrantReadWriteLockPessimistic reading and writingOptimistic readingConditional changes by upgrading read to write lockPerformance differences between StampedLock and ReentrantReadWriteLockDay 312 Building Custom SynchronizersManaging state dependenceSingle-threaded vs multi-threadedStructure of blocking state-dependent actionsExample using bounded queuesIntroducing condition queuesWith intrinsic locksUsing condition queuesState-dependenceCondition predicateLockCondition queueWaking up too soonWaiting for a specific timeoutConditional waitsMissed signalsInterruptedExceptionnotify() vs notifyAll()Encapsulating condition queuesExplicit condition objectsCondition interfaceBenefits of explicit condition queuesTimed conditions13 Atomic Variables and Nonblocking SynchronizationDisadvantages of lockingElimination of uncontended intrinsic locksVolatile vs locking performancePriority inversionHardware supportOptimistic lockingCompare-and-Swap (CAS)Compare-and-SetManaging conflicts with CASSimulation of CASNonblocking counterCAS support in the JVMShared cache linesPerformance advantage of paddingUsing @sun.misc.Contended (Java 8)Atomic variable classesOptimistic locking classesVery fast when not too much contentionTypes of atomic classesHow do atomics work?Atomic array classesLongAdder and LongAccumulator (Java 8)Performance comparisons: Locks vs atomicsCost of atomic spin loopsNonblocking algorithmsScalability problems with lock-based algorithmsDefinition of nonblocking and lock-freeNonblocking stackDoing speculative workPerformance14. Java MemoryGarbage CollectionGenerational SpacesDifference between young and old GCStop-The-World eventsThroughput Collector (Parallel)How it worksTuning the throughput collectorConcurrent Mark Sweep CollectorVarious phases either STW or ConcurrentTypes of serious STW failuresConcurrent Mode FailurePromotion FailedPerm/Meta GCTuning the throughput collectorG1 CollectorHow it worksTuning the G1 collectorSizing the collectorTotal HeapNew/OldEden/SurvivorTenuring thresholdWorking example in tuning a large Fibonacci number calculationMeasuring GC ActivityFlags for generating GC logsUnderstanding GC informationReferencesReference ObjectsObject ReachabilityUsing ReferencesSoftReferenceWeakReferencePhantomReference15. Java OptimizationsTuning ProcessOptimization Techniques - Big Gains QuicklySpecifying the required performanceOptimization methodologySystem Overview - "The Box"Analyzing CPU bottlenecksMicrobenchmarkingJava Microbenchmarking Harness (JMH)JIT and HotSpotJust-in-TimeHotSpotClientServerTiered CompilationVM SwitchesEffects on performance and benchmarkingTypical Problem AreasObject CreationArray creationTemporary objectsLazy initializationStringsinternStringBuilder vs StringBuffer vs Stringchar[] creation with modifying methods+= complexityString appending performanceParsing Stringssubstring() in various versions of JavaString deduplication (Java 8)Regular ExpressionsException performanceLoopsTuning loopsExtracting invariantsMethod callsArrays and loopsCache linesCalls to JNIBenchmarkingOther AreasFinal16 ConclusionTips on where to learn moreThank you!
  • Day 1
    • 1 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
    • 2 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
    • 3 Building Blocks
      • Synchronized collections
        • Old Java 1.0 thread-safe containers
        • Synchronized wrapper classes
        • Locking with compound actions
      • Concurrent collections
        • Scalability
        • ConcurrentHashMap
          • New Java 8 methods
        • 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)
    • 4 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
    • 5 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

  • Day 2
    • 6 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
    • 7 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
    • 8 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 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
    • 9 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
    • 10 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
    • 11 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

  • Day 3
    • 12 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
    • 13 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
      • 14. 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
      • 15. 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
    • 16 Conclusion
      • Tips on where to learn more
      • Thank you!


About the Author

Heinz Kabutz Java Conference Speaker

Java Champion, author of the Javaspecialists Newsletter, conference speaking regular... About Heinz

Superpack '23

Superpack '24 Our entire Java Specialists Training in one huge bundle more...

Free Java Book

Dynamic Proxies in Java Book

110% Money-back Guarantee

Should you not be satisfied with the quality of the training or the delivery, we will gladly refund you 100% of the course fees. This needs to be brought to our attention within the first 4 hours of the course and a chance should be given to correct whatever you are not satisfied with. If you are still not satisfied, we will refund you 100% of the course fees, plus we will pay our own travel expenses. The training material then remains the property of JavaSpecialists.EU.


Cancellation Policy

If the course is cancelled more than two weeks before the start of the course, a 10% cancellation fee of the fees will apply, plus any non-refundable travel expenses incurred by the trainer.

If the course is cancelled within two weeks of the start of the course, a 50% cancellation fee of the fees will apply, plus any non-refundable travel expenses incurred by the trainer.

No refund will be given to cancellations during the course.


Java Training

We deliver relevant courses, by top Java developers to produce more resourceful and efficient programmers within their organisations.

Java Consulting

We can help make your Java application run faster and trouble-shoot concurrency and performance bugs...