Hi all..Have you tried to perform concurrent operations with Java? What are they? Let me introduce. Sometimes we can do several things parallel at the same time with the computers like browsing using chrome, listening to music on player, writing into a word document and etc. So like this, Java provides a way to handle simultaneous operations in our applications. That is called as Threads. This is a bit long article since I have to cover a lot of concepts. So, your patience is more important. 


Java Thread

A thread is a lightweight sub-process, the smallest unit of processing. The idea of introducing threads is to achieve parallelism by dividing a process into multiple threads. Each Java program has at least one thread known as the main thread.


Thread Life Cycle

Usually threads have several states. Any thread can be in one and only state at a time. With theses states a thread has a life cycle which describes the switching between the states.


  1. NEW – Newly created thread that has not yet started the execution falls under this state. It is known as born thread.
  2. RUNNABLE – The thread that is either running or ready for execution by calling start method. It becomes intermediate state; RUNNING when run() method is called.
  3. BLOCKED – Thread is waiting to acquire a monitor lock to enter or re-enter a synchronized block/method
  4. WAITING – Thread is waiting for some other thread to perform a particular action without any time limit. When wait() method is performed, the object referred in the thread goes to waiting state. If we want to wake up a single thread and get it back to runnable state that is waiting on this object's monitor, notify() method should be called. notifyAll() method is performed when we have to convert all the threads waiting on this object's monitor into runnable.
  5. TIMED_WAITING – Thread is waiting for some other thread to perform a specific action for a specified period
  6. TERMINATED – Thread has completed its execution


Implementation of Threads in Java

In Java, there are two main ways to create a thread. They are;
  1. Extending Thread class
  2. Implementing Runnable interface

Let's see how to create threads using these two methods.

Both ways must override the method run by providing the logic that is needed to be executed simultaneously.


In this Java code, ThreadOne is created by extending the Thread class. And ThreadTwo is created by implementing the Runnable interface. Using Thread class as a static reference, we can get Thread name using Thread.currentThread().getName() statement. By default Java assigns thread names as "Thread-0". We can pass any name for the thread we create using Constructor of the thread class.

NOTE:
When we use Runnable, we get additional benefit. Inheritance using a super class is blocked when we extend from Thread class. But when we use Runnable, we can use another super class also with it allowing multiple inheritance.


Methods available in Threads

There are commonly used set of methods available in Java threads. Let me describe them one by one.

1. start( )
This is the method used for executing a thread. Whenever we call this method it internally invokes the run method inherited from Thread class or Runnable interface.

2. run( )
When thread is executed, this method is invoked by start method.

3. sleep( )
If we want to pause the execution of any thread, we can use this method. Sleep method takes an argument which is reserved for the time that the pause should be there. We have to give the time duration in milliseconds. e.g. : 1 second -> 1000
So this method guarantees the time when the thread is scheduled back.

4. join( )
When there's a requirement to execute a thread one after the other, like a serial schedule, we can use join method. Let's consider the example from the thread implementation code we used before.
If we use threadOne.join() or threadTwo.join() line within the main thread, we can see always the 2 threads are executing one after the other. No simultaneous executions are allowed.

5. yield( )
When yield is called, the current thread simply gives the chance to CPU to pick another thread but does not block a thread. In another way, the current thread is willing to relinquish its current use of processor but it would like to be scheduled back soon as possible. But no guarantee of when will it be scheduled back unlike sleep method.

6, wait( )
The Object class of Java is having wait(), notify() and notifyAll() methods. This method can only be invoked within a synchronized block. It instruct the calling thread to release lock and go to sleep, until some other thread enters the same monitor and invoke notify() method. Wait method releases the lock before going to waiting state and acquire again it before returning from wait.

7. notify( )
This method wakes up a single thread on which wait method was called, on the same object. This method also can only be invoked within a synchronized block.

8. notifyAll( )
This method wakes up a all threads on which wait method was called, on the same object. This method also can only be invoked within a synchronized block as notify().


NOTE:
All 3 methods - wait(), notify() and notifyAll() are associated with Object class. So there should be an access to an object to use these methods.


Synchronization

Synchronization in java is the capability to control the access of multiple threads to any shared resource.
So after synchronization, one thread will access the resource at a time! Synchronized keyword is used to lock an object. When a thread invokes a synchronized method, it automatically acquires the lock for that object and releases it when the thread completes its task. If any static method is made as synchronized, the lock will be on the class not on object. There are 2 ways to use synchronized key word in Java. They are,

1. Synchronized method
This will synchronize the whole method and only one thread at a time access the method.

2. Synchronized block

This synchronizes only the needed code block and then only one thread at a time access the the code within this block.

Look at the below example code.

As you can see in the code,  getAccess() method has been synchronized. The output has been printed in a way that R is accessed only by Thread-1 after releasing the lock by Thread-0. Remove the synchronized keyword and see the result. R will be accessed simultaneously by two threads; t1 and t2.
Rather than making the whole method synchronized, we can synchronize only a block within the method. Then multiple threads can access the method but not the logic of the method coded within a synchronized block. However, synchronization slows down the processing.


Thread Pool Executor

ThreadPoolExecutor​ separates the task creation and its execution. With
ThreadPoolExecutor​ , you only have to implement the Runnable​ objects and send them to the executor. Thread Pool manages the pool of worker threads by maintaining a queue to hold tasks that are going to be executed next.



Types of ThreadPool Executors

1. Fixed thread pool executor :
Creates a thread pool that reuses a fixed number of threads to execute any number of tasks.

2. Cached thread pool executor :​ 
Creates a thread pool that creates new threads as needed

3. Scheduled thread pool executor :
Creates a thread pool that can schedule commands to run after a given delay, or to execute periodically.

4. Single thread pool executor :​
Creates single thread to execute all tasks. Use it when you have only one task to execute.

5. Work stealing thread pool executor : 
Creates a thread pool that maintains enough threads to support the given parallelism level.Here parallelism level means the maximum number of threads which will be used to execute a given task, at a single point of time, in multi-processor machines.

Let's move into a code sample.

Here I create a Fixed thread pool executor. The parameter passed into this is the number of threads going to work on our worker threads(Tasks). You can see the time taken to display the result is increased when we increase this parameter which means more threads are working on our tasks concurrently.


Runnable VS Callable

Both are available in Thread API, to be used as interfaces. Both are functional interfaces.

1. Availabiltiy
Runnable - from JDK 1.0
Callable - from JDK 1.5

2. Result
Runnable - can not return a result of a parallel execution of a task. It return as a Future object.
Callable - can return a result

3. Exceptions
Runnable - run method can not throw checked exceptions
Callable - run method can throw 

4. Thread implementation
Runnable - uses run( ) method
Callable - uses call( ) method

Since you have already seen the way to implement with Runnable, now let's move to the implementation of Callable. Result is returned as a Future object. We are using ThreadPool also in this code.


Following the Threads in Java, I have explained some concepts in the article. So, we have come to the end of this article. I hope you got a great understanding on Threads in Java. Practice is the key to understand most of the concepts. So, Practice guys!!!

Good Bye!!!





4 Comments

  1. Thanks, this is generally helpful.
    Still, I followed step-by-step your method in this Java online training
    java online training india

    ReplyDelete
  2. Renting a wedding transportation services offers a spacious and convenient solution for larger groups or families seeking comfortable and versatile transportation. These vehicles are designed to accommodate up to seven passengers comfortably while still providing ample cargo space for luggage or equipment.

    ReplyDelete
  3. Looking for a reliable Airport shuttle Jacksonville? Look no further! Our experience with [insert shuttle service name] was fantastic. Prompt pickup, courteous drivers, and comfortable rides make it our top choice every time we fly in or out of Jacksonville.

    ReplyDelete
  4. Without a doubt, Best limousine car service has set the standard for luxury transportation. From their impeccably maintained fleet to their professional and courteous chauffeurs, every aspect of their service exudes excellence.

    ReplyDelete