Multithreading

Intrinsic Lock
  • Synchronisation is internally controlled by an entity known as the intrinsic lock or monitor lock.
  • Intrinsic locks play a role in both aspects of synchronisation Thus enforcing exclusive access to an objects State to one thread and preventing access to other threads And establishing happens before relationships that are essential to visibility.
  • Every object has an associated intrinsic lock. A thread that needs Exclusive and consistent access to an objects fields Has to acquire the objects intrinsic lock Before accessing them, and then release the intrinsic lock when done. As long as a thread Owns an intrinsic lock, No other thread Can acquire the same lock, the other thread will block.
Fork Join framework
  • Fork Join framework Was introduced in Java 1.7
  • Package is java.util.concurrent
  • It is a Java framework that takes the advantage of multiple processors by breaking down a large task Into smaller tasks that can be run in parallel.
  • The goal is to balance the workload between threads and maximise CPU utilisation.
  • It is the specialised implementation of Executor service interface.
  • It works on work, stealing algorithms.
  • In executor framework We have a thread pool And in that pool, we will have specific number of threads to execute the task. We also have a blocking Queue where Extra task will wait until any worker is available.
  • Fork join Framework is specifically designed for tasks that can be broken down into smaller sub tasks, which are then executed and the results are merged(A divide and conquer approach). It uses a special type of thread pool called as fork join pool.
  • It also uses work stealing algorithms to maximise the CPU utilisation.
  • The common queue Serves as a centralised repository for tasks submitted to the fork join pool For execution.
  • When you submit tasks to the pool, they are added to this queue.
  • If worker thread finish their task They can steal some tasks from other working threads.
  • Fork breaks down a large task into smaller sub tasks.
  • Join waits for the result of sub tasks and combine them to produce the final result.
  • At the core of the Fork/Join Framework. There are four main classes.
    • Fork Join Task<V>
      • It is an abstract class
      • It defines a task that can be executed inside a fork join pool.
      • V The generic parameter specifies the result of the task
      • ForkJoinTask Are very efficient than threads.
      • Some important methods are
        • Final ForkJoinTask<V> fork():
          • This method tells a task to start executing asynchronously.
          • This method can be used when we have a task that can be divided into smaller, sub tasks that can be executed concurrently.
        • Final V Join()
          • This Method waits for result of Subtasks.
        • Final V invoke()
          • It combines fork join Operations into a single call because it begins a task and wait for it to complete.
        • Static void invokeAll(ForkJoinTask<?> t1,ForkJoinTask<?> t2)
          • Invokes more than one task At a time. Both t1 and t2 tasks are executed.
        • Static void invokeAll(ForkJoinTask<?>…tasks)
          • Here All specific tasks are executed.
    • Fork Join pool.
      • Introduced in Java 1.7 version.
      • It is designed to efficiently execute tasks that can be broken down into smaller sub tasks, specially in multi core environments.
      • It uses a work stealing algorithm where idle threads Can steel tasks from other threads work queues.
      • In order to execute ForkJoinTask, You must first have a ForkJoinPool
      • Two constructors are
        • Fork Join pool()
          • It creates a default pool that supports a level of parallelism equal to the number of processors available In the system.
        • ForkJoin(int parallelism)
          • It specify The level of parallelism. It means the given number of worker thread created into the pool.
          • The level of parallelism determines the number of threads That can be executed concurrently.
      • Important methods are
        • <T> T invoke(ForkJoinTask<T> task)
          • Initiate the parallel execution of given task, wait for its completion and returns. The result of the task.
        • Void execute (ForkJoinTask<T> task)
          • If you want to start a task Without waiting for its completion, you can use execute method. It executes the given task asynchronously.
        • Static ForkJoin commonpool()
          • We can use this common pool to run tasks without having to set up your own pool of threads.
          • Java takes care of common pool like Creating or managing threads.
          • If you need custom configuration like parallelism level, thread creation, Exception handling, et cetera Then you should not use the common pool().
      • Examples
    • Recursive Action
      • It represent a task that does not return the value.
      • It extends ForkJoin<void>. However Since it does not produce a result, it is Parameterised with void.
      • Important methods are
        • Protected abstract void, compute()
          • This method defines actual work to be performed by the task. It’s where you write the code to perform the action or modification.
          • Here, protected and abstract method means it must be implemented by a sub class.
      • RecursiveAction Task often use a divide and conquer approach, where the task divides itself into smaller sub tasks until each sub task can be performed independently. Once the smallest task are reached, they perform the action directly.
      • Example
    • Recursive Task<V>
      • It represent a task that returns the value.
      • It’s particularly useful for tasks that can be Recursively split into sub task and results of these sub tasks need to be combined to produce the final result.
      • Important methods are
        • Protected abstract V compute()
          • Here, protected and abstract methods means, it must be implemented by a sub class.
          • V represent The result types.
      • Recursive task Use a divide and conquer approach.
      • A large task is divided into smaller, subtasks Until they are small enough to solve directly.
      • Then the result of the sub tasks is combined together to produce the final result.
      • Example
  • Fork Join task Is an abstract class that represent a task that can be executed asynchronously In Fork Join Pool.
  • Fork Join Pool Manages the Execution of Fork Join Tasks.
  • Recursive action Is a sub class of ForkJoinTask<Void>, That represent A task that does not returns a value.
  • Recursive Task<V> a sub class of a fork join task<V>, That represent a task that returns a value.
  • ForkJoinTask<V> For representing tasks.
  • ForkJoinPool For managing threads And executing tasks.
  • RecursiveAction And RecursiveTask<V> as subclasses of ForkJoinTask<V> For defining tasks that perform Actions Computations, respectively.
  • Future is the interface Implemented by ForkJoinTask
  • ExecutorService Is the interface implemented By AbstractExecutor Services Which is the parent class of ForkJoinPool.
Count down latch
Multithreading
  • Multithreading is a process of executing two or more threads simultaneously.
  • When two or more threads, try to update the mutually shared resource(data) At the same time, a race condition may occur.
Deadlock
  • It occurs when two threads have a circular dependency on a pair of synchronised objects.
  • It is difficult to find error or to debug Because it occurs rarely when the time slice is just right and also may involve more than two threads and two synchronised objects.
Synchronised
  • Synchronised allows only a single thread at a time To access the shared resource, and forces, all other threads To wait for that access thread To release its access to the shared resources.
    • Each object has a unique lock in Java.
    • Synchronised can be applied on Methods/blocks
    • Access on an object. Only one thread can execute a synchronised block at a time.
    • This process is mutually exclusive among threads.
  • Synchronised is applicable on methods and blocks.
  • Synchronised can be used to implement lock based Algorithms
  • Because of acquire and release lock perform means it’s Performance is low.
  • No possibility of deadlock or live lock In synchronised
  • Synchronisation helps to achieve the access of one resource by only One thread at a time.
  • In Java the synchronisation takes place With the help of monitor.
  • Only one thread can own a monitor at a given time.
  • Once a thread enters any synchronised Method on an instance, no other thread can enter any other synchronise method On the same instance.
  • Non-synchronised methods on that instance will continue to be Callable.
  • All the methods with synchronised keyword will have a single point of access that is through one thread.
  • There are two Mode of synchronisation
    • Method synchronisation
    • Block synchronisation
      • We can specify a block as synchronised by passing the reference to an object, which has the monitor.
  • We should use synchronisation when a method or a group of methods that manipulate the internal state of an object in a multithread situation.
    • Helps us to guard, the state from race condition.
Monitor
  • A monitor is an object that is used as a mutually exclusive lock.
  • All the objects have their own implicit monitor associated with them.
  • To enter an objects, monitor We call the methods modified with synchronise keyword.
  • All the other threads attempting to enter the locked monitor will be suspended until the first thread exit, the monitor.
  • A thread That owns Monitor can re-enter the same monitor, if so, it desires.
Cache Incoherence
  • Each thread has a copy of variable in its cache This can lead to inconsistency of data. This is called cache coherence.
  • Volatile save this by guarantee of visibility of variable.
  • A write to Volatile field happens before every subsequent read of that field.
  • Volatile is applicable on variables
  • Volatile can be used to implement non-lock based algorithms.
  • Volatile is relatively faster than synchronised
  • Possibility of deadlock and live lock is there in volatile.
Atomic Variable
  • Atomic variable guarantee that operations Made on the variable occur in an atomic fashion.
  • Classes from package, Java.util.concurrent.atomic
  • Example atomic integer, atomic long, atomic boolean, atomic reference.
  • Atomic is applicable only on Variables
  • Atomic can be used to implement non-lock based algorithms
  • Atomic is faster than synchronised and volatile
  • Possibility of deadlock and live lock is there in atomic.
Synchronised Method and Synchronised Block
  • Synchronise methods The lock will be held through out the method scope. While in synchronised block, The Lock is held only during block scope.
  • Synchronise method locks on the object, instance, the method is contained in a while a synchronise block can lock any object.
  • Synchronise block provides granular control over lock, as you can use any lock to provide mutual exclusion to critical section code. Synchronise method always locks either on different object, object or class level. If it is static synchronised method.
  • Synchronise block:
    • synchronised(this){}
  • Synchronised Method
    • public synchronised void function(){}
Static synchronisation
  • Used when a lock is acquired at class level.
Different states of a thread
  • A thread goes In waiting, state when weight is called. It will release all its resources.
  • When sleep is called, it goes in the sleep state, but does not release all its resources.
  • When the sleep is done, it again goes into waiting state.
  • When notify/notify all is called, it, reactivate the waiting thread.
We can create threads in Java using Runnable and Thread class.
  • When we create a Thread using Thread class we cannot reuse it once it gets completed.
  • Using Runnable we can decide in advance how many threads we want to create
    • Then we create a third pool with those many threads.
    • Once a thread has completed a task it will again be placed in the third pool.
    • If we don’t create a thread pool then we will have to create a new thread each time which is a costly affair.
    • If a thread terminates unexpectedly a new thread is automatically added to the pool.
Thread Pools
  • By creating a thread pool we can control how many threads are active at a time.
  • Each thread pool has an internal task queue.
  • A thread pool is a collection of pre initialised thread’s That are ready to execute tasks. Instead of creating a new trade for every task, you can borrow one from the pool. Use it, and then return it back to the pool when done.
  • Threads are already created eliminating the overhead of creation time.
  • Limits the number of active threats, avoiding resource exhaustion.
  • Simplify threat life-cycle management, including creation, execution, and termination
  • Can adapt to change in workload by dynamically resizing the pool.
  • Utilised in web servers, parallel processing, task, scheduling, and much more
Lock
  • Lock provides an alternatives to the use of synchronised methods.
  • Before accessing a shared resource, the lock that protects that resource is acquired. When access to resource is complete, the lock is released.
  • If the second thread Attempts to acquire the lock that is in use by another thread, The second third will suspend until the lock is released.
Read Write Locks
  • This interface simplifies a lock That maintain separate locks for read and write access.
  • This enables multiple locks to be granted For readers of a resource as lock as the resource is not being written.
  • ReenterantReadWriteLock Provides an implementation of read write lock.
Executor Framework
  • Executor framework came since Java 1.5
  • Executive framework is a component of Java’s java.util.concurrent Package which manages the thread execution in concurrent programming.
  • Just like how our team of cooks can prepare different dishes at the same time, the framework uses a team of worker threads to handle multiple tasks together
  • Executor service Uses thread pools Internally, where threads are reused and Recycled.
  • Executor service decouples the task submission from thread creation And management services.
  • Each thread in the pool executes tasks, one by one form queue.
  • Benefits
    • Efficient thread management
    • Simplified thread life-cycle management.
  • Shutdown method
    • Method of executor service, which shuts down the executor After all, the tasks have been completed.
  • New single thread executor method
    • Provide facilities to execute one thread at a time.
    • Single thread executor Is a special case of fixed thread executor.
      • Pool size is set to 1
    • All tasks are run in sequence by a single thread.
  • New fixed thread pool method
    • Creates a pool of n fixed threads Which run parallel and share same queue for tasks.
  • New cached thread pool method
    • Continues creating threads As long as there are Tasks available for execution and no threads are available.
    • There is no limit on the number of threads created to execute a task.
    • The concept of wait Queue is not there.
  • Is shut down method
    • Check if the executor service is shut down or not.
  • Classes/Interface of executor framework.
    • Executor Interface
      • Main interface that represents an object capable of executing tasks.
      • Contains a single method, void, execute(Runnable task)
      • Has execute method which is used to execute runnable tasks.
      • Decouples the task from threads
    • Executive service Interface extends Executor Interface
      • Sub interface of executor
      • Provide a higher level of API for management of thread execution.
      • Offers methods for task submission, termination, and more.
      • Provide the function to manage the lifetime of executor
        • Init
        • Service
        • Destroy
    • Executors
      • Thread Pool Executor class
        • The most commonly used implementation of the Executor service.
        • Manages the pool of worker threads for executing tasks.
        • Allows customisation of thread pool size, thread execution policies, And more.
      • Executor class
        • Utility class that provides factory methods for creating different types of executor service instances.
    • Future
  • Executor life-cycle
    • Submit task
      • Tasks are submitted to the executor service.
      • Can be represented as runnable or callable objects
    • Task queueing
      • Tasks are stored in a queue until a worker thread becomes available.
    • Thread execution
      • Worker threads Execute tasks, concurrently.
    • Thread termination
      • Executor service manages The life cycle of worker threads.
      • Threads are reused If more tasks are available reducing overhead.
  • Source Code at:

No comments:

Post a Comment