Multithreading is a programming technique which consists of dividing a task into separate threads of execution. These threads run concurrently, either by being assigned to different processing cores, or by time-slicing.
When designing a multithreaded program, the threads should be made as independent of each other as possible, to achieve the greatest speed-up.
In practice the threads are rarely fully independent, which makes synchronisation necessary.
The maximum theoretical speed-up can be calculated using Amdahl's law.
Advantages
Disadvantages
The different types of Threadpools and Queues that are explained below, have been taken from the information and knowledge from [oracle documentation][1] and [Jakob Jenkov][2] blog where you can learn a lot about concurrency in java.
SingleThreadExecutor: Executor that uses a single worker thread operating off an unbounded queue, and uses the provided ThreadFactory to create a new thread when needed. Unlike the otherwise equivalent newFixedThreadPool(1, threadFactory) the returned executor is guaranteed not to be reconfigurable to use additional threads.
FixedThreadPool: thread pool that reuses a fixed number of threads operating off a shared unbounded queue, using the provided ThreadFactory to create new threads when needed. At any point, at most nThreads threads will be active processing tasks. If additional tasks are submitted when all threads are active, they will wait in the queue until a thread is available. If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks. The threads in the pool will exist until it is explicitly shutdown.
CachedThreadPool: Thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available, and uses the provided ThreadFactory to create new threads when needed.
SingleThreadScheduledExecutor: Single-threaded executor that can schedule commands to run after a given delay, or to execute periodically. (Note however that if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.) Tasks are guaranteed to execute sequentially, and no more than one task will be active at any given time. Unlike the otherwise equivalent newScheduledThreadPool(1, threadFactory) the returned executor is guaranteed not to be reconfigurable to use additional threads.
ScheduledThreadPool: Thread pool that can schedule commands to run after a given delay, or to execute periodically. Different types of Work Queues
Here's a brilliant explanation from this Stackoverflow question:
Think of semaphores as bouncers at a nightclub. There are a dedicated number of people that are allowed in the club at once. If the club is full no one is allowed to enter, but as soon as one person leaves another person might enter.
It's simply a way to limit the number of consumers for a specific resource. For example, to limit the number of simultaneous calls to a database in an application.
A mutex is a semaphore of 1 (i.e. only one thread at a time). Using the nightclub metaphor, think of a mutex in terms of a bathroom stall in the nightclub. Only one occupant allowed at a time.