Author(s): Javier Fernández González
Edition: 2
Publisher: Packt Publishing
Year: 2017
Language: English
Pages: 507
Tags: java thread concurrent reactive streams
Cover
Copyright
Credits
About the Author
About the Reviewer
www.PacktPub.com
Customer Feedback
Table of Contents
Preface
Chapter 1: The First Step - Concurrency Design Principles
Basic concurrency concepts
Concurrency versus parallelism
Synchronization
Immutable object
Atomic operations and variables
Shared memory versus message passing
Possible problems in concurrent applications
Data race
Deadlock
Livelock
Resource starvation
Priority inversion
A methodology to design concurrent algorithms
The starting point - a sequential version of the algorithm
Step 1 - analysis
Step 2 - design
Step 3 - implementation
Step 4 - testing
Step 5 - tuning
Conclusion
Java Concurrency API
Basic concurrency classes
Synchronization mechanisms
Executors
The fork/join framework
Parallel streams
Concurrent data structures
Concurrency design patterns
Signaling
Rendezvous
Mutex
Multiplex
Barrier
Double-checked locking
Read-write lock
Thread pool
Thread local storage
Tips and tricks for designing concurrent algorithms
Identifying the correct independent tasks
Implementing concurrency at the highest possible level
Taking scalability into account
Using thread-safe APIs
Never assume an execution order
Preferring local thread variables over static and shared when possible
Finding the easier parallelizable version of the algorithm
Using immutable objects when possible
Avoiding deadlocks by ordering the locks
Using atomic variables instead of synchronization
Holding locks for as short a time as possible
Taking precautions using lazy initialization
Avoiding the use of blocking operations inside a critical section
Summary
Chapter 2: Working with Basic Elements - Threads and Runnables
Threads in Java
Threads in Java - characteristics and states
The Thread class and the Runnable interface
First example: matrix multiplication
Common classes
Serial version
Parallel versions
First concurrent version - a thread per element
Second concurrent version - a thread per row
Third concurrent version - the number of threads is determined by the processors
Comparing the solutions
Second example - file search
Common classes
Serial version
Concurrent version
Comparing the solutions
Summary
Chapter 3: Managing Lots of Threads - Executors
An introduction to executors
Basic characteristics of executors
Basic components of the Executor framework
First example - the k-nearest neighbors algorithm
k-nearest neighbors - serial version
K-nearest neighbors - a fine-grained concurrent version
k-nearest neighbors - a coarse-grained concurrent version
Comparing the solutions
Second example - concurrency in a client/server environment
Client/server - serial version
The DAO part
The command part
The server part
Client/version - parallel version
The server part
The command part
Extra components of the concurrent server
The status command
The cache system
The log system
Comparing the two solutions
Other methods of interest
Summary
Chapter 4: Getting the Most from Executors
Advanced characteristics of executors
Cancellation of tasks
Scheduling the execution of tasks
Overriding the executor methods
Changing some initialization parameters
First example - an advanced server application
The ServerExecutor class
The statistics object
The rejected task controller
The executor tasks
The executor
The command classes
The ConcurrentCommand class
The concrete commands
The server part
The ConcurrentServer class
The RequestTask class
The client part
Second example - executing periodic tasks
The common parts
The basic reader
The advanced reader
Additional information about executors
Summary
Chapter 5: Getting Data from Tasks - The Callable and Future Interfaces
Introducing the Callable and Future interfaces
The Callable interface
The Future interface
First example - a best-matching algorithm for words
The common classes
A best-matching algorithm - the serial version
The BestMatchingSerialCalculation class
The BestMachingSerialMain class
A best-matching algorithm - the first concurrent version
The BestMatchingBasicTask class
The BestMatchingBasicConcurrentCalculation class
A best-matching algorithm - the second concurrent version
Word exists algorithm - a serial version
The ExistSerialCalculation class
The ExistSerialMain class
Word exists algorithm - the concurrent version
The ExistBasicTasks class
The ExistBasicConcurrentCalculation class
The ExistBasicConcurrentMain class
Comparing the solutions
Best-matching algorithms
Exist algorithms
The second example - creating an inverted index for a collection of documents
Common classes
The Document class
The DocumentParser class
The serial version
The first concurrent version - a task per document
The IndexingTask class
The InvertedIndexTask class
The ConcurrentIndexing class
The second concurrent version - multiple documents per task
The MultipleIndexingTask class
The MultipleInvertedIndexTask class
The MultipleConcurrentIndexing class
Comparing the solutions
Other methods of interest
Summary
Chapter 6: Running Tasks Divided into Phases - The Phaser Class
An introduction to the Phaser class
Registration and deregistration of participants
Synchronizing phase change
Other functionalities
First example - a keyword extraction algorithm
Common classes
The Word class
The Keyword class
The Document class
The DocumentParser class
The serial version
The concurrent version
The KeywordExtractionTask class
The ConcurrentKeywordExtraction class
Comparing the two solutions
The second example - a genetic algorithm
Common classes
The Individual class
The GeneticOperators class
The serial version
The SerialGeneticAlgorithm class
The SerialMain class
The concurrent version
The SharedData class
The GeneticPhaser class
The ConcurrentGeneticTask class
The ConcurrentGeneticAlgorithm class
The ConcurrentMain class
Comparing the two solutions
Lau15 dataset
Kn57 dataset
Conclusions
Summary
Chapter 7: Optimizing Divide and Conquer Solutions - The Fork/Join Framework
An introduction to the fork/join framework
Basic characteristics of the fork/join framework
Limitations of the fork/join framework
Components of the fork/join framework
The first example - the k-means clustering algorithm
The common classes
The VocabularyLoader class
The word, document, and DocumentLoader classes
The DistanceMeasurer class
The DocumentCluster class
The serial version
The SerialKMeans class
The SerialMain class
The concurrent version
Two tasks for the fork/join framework - AssignmentTask and UpdateTask
The ConcurrentKMeans class
The ConcurrentMain class
Comparing the solutions
The second example - a data filtering algorithm
Common features
The serial version
The SerialSearch class
The SerialMain class
The concurrent version
The TaskManager class
The IndividualTask class
The ListTask class
The ConcurrentSearch class
The ConcurrentMain class
Comparing the two versions
The third example - the merge sort algorithm
Shared classes
The serial version
The SerialMergeSort class
The SerialMetaData class
The concurrent version
The MergeSortTask class
The ConcurrentMergeSort class
The ConcurrentMetaData class
Comparing the two versions
Other methods of the fork/join framework
Summary
Chapter 8: Processing Massive Datasets with Parallel Streams - The Map and Reduce Model
An introduction to streams
Basic characteristics of streams
Sections of a stream
Sources of a stream
Intermediate operations
Terminal operations
MapReduce versus MapCollect
The first example - a numerical summarization application
The concurrent version
The ConcurrentDataLoader class
The ConcurrentStatistics class
Customers from the United Kingdom
Quantity from the United Kingdom
Countries for product
Quantity for product
Multiple data filter
Highest invoice amounts
Products with a unit price between 1 and 10
The ConcurrentMain class
The serial version
Comparing the two versions
The second example - an information retrieval search tool
An introduction to the reduction operation
The first approach - full document query
The basicMapper() method
The Token class
The QueryResult class
The second approach - reduced document query
The limitedMapper() method
The third approach - generating an HTML file with the results
The ContentMapper class
The fourth approach - preloading the inverted index
The ConcurrentFileLoader class
The fifth approach - using our own executor
Getting data from the inverted index - the ConcurrentData class
Getting the number of words in a file
Getting the average tfxidf value in a file
Getting the maximum and minimum tfxidf values in the index
The ConcurrentMain class
The serial version
Comparing the solutions
Summary
Chapter 9: Processing Massive Datasets with Parallel Streams - The Map and Collect Model
Using streams to collect data
The collect() method
The first example - searching data without an index
Basic classes
The Product class
The Review class
The ProductLoader class
The first approach - basic search
The ConcurrentStringAccumulator class
The second approach - advanced search
The ConcurrentObjectAccumulator class
A serial implementation of the example
Comparing the implementations
The second example - a recommendation system
Common classes
The ProductReview class
The ProductRecommendation class
Recommendation system - the main class
The ConcurrentLoaderAccumulator class
The serial version
Comparing the two versions
The third example - common contacts in a social network
Base classes
The Person class
The PersonPair class
The DataLoader class
The concurrent version
The CommonPersonMapper class
The ConcurrentSocialNetwork class
The ConcurrentMain class
The serial version
Comparing the two versions
Summary
Chapter 10: Asynchronous Stream Processing - Reactive Streams
Introduction to reactive streams in Java
The Flow.Publisher interface
The Flow.Subscriber interface
The Flow.Subscription interface
The SubmissionPublisher class
The first example - a centralized system for event notification
The Event class
The Producer class
The Consumer class
The Main class
The second example - a news system
The News class
The publisher classes
The Consumer class
The Main class
Summary
Chapter 11: Diving into Concurrent Data Structures and Synchronization Utilities
Concurrent data structures
Blocking and non-blocking data structures
Concurrent data structures
Interfaces
BlockingQueue
BlockingDeque
ConcurrentMap
TransferQueue
Classes
LinkedBlockingQueue
ConcurrentLinkedQueue
LinkedBlockingDeque
ConcurrentLinkedDeque
ArrayBlockingQueue
DelayQueue
LinkedTransferQueue
PriorityBlockingQueue
ConcurrentHashMap
Using the new features
First example with ConcurrentHashMap
The forEach() method
The search() method
The reduce() method
The compute() method
Another example with ConcurrentHashMap
An example with the ConcurrentLinkedDeque class
The removeIf() method
The spliterator() method
Atomic variables
Variable handles
Synchronization mechanisms
The CommonTask class
The Lock interface
The Semaphore class
The CountDownLatch class
The CyclicBarrier class
The CompletableFuture class
Using the CompletableFuture class
Auxiliary tasks
The main() method
Summary
Chapter 12: Testing and Monitoring Concurrent Applications
Monitoring concurrency objects
Monitoring a thread
Monitoring a lock
Monitoring an executor
Monitoring the fork/join framework
Monitoring a Phaser
Monitoring the Stream API
Monitoring concurrency applications
The Overview tab
The Memory tab
The Threads tab
The Classes tab
The VM summary tab
The MBeans tab
The About tab
Testing concurrency applications
Testing concurrent applications with MultithreadedTC
Testing concurrent applications with Java Pathfinder
Installing Java Pathfinder
Running Java Pathfinder
Summary
Concurrency in JVM - Clojure and Groovy with the Gpars Library and Scala
Concurrency in Clojure
Using Java elements
Reference types
Atoms
Agents
Refs
Delays
Futures
Promises
Concurrency in Groovy with the GPars library
Software transactional memory
Using Java elements
Data parallelism
The fork/join processing
Actors
Agent
Dataflow
Concurrency in Scala
Future objects in Scala
Promises
Summary
Index