Java Specialists' Java Training Europehome of the java specialists' newsletter

Extreme Java - Concurrency Performance for Java 8 Course Outline

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

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!

Make Enquiry

 


1. Course Overview 2. Course Outline
Extreme Java - Concurrency and Performance for Java 8
Extreme Java - Advanced Topics for Java 8
Design Patterns
In-House Courses

© 2010-2016 Heinz Kabutz - All Rights Reserved Sitemap
Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners. JavaSpecialists.eu is not connected to Oracle, Inc. and is not sponsored by Oracle, Inc.