Why do we need a Thread and What is Thread ?

 

Why do we need a Thread ?

Let’s just say you are new to felight.io (felight.com), so you go ahead, fill the web form and click on register. How much longer you wait for the success message ?

Almost instantly !!, isn’t it ?

But you will receive a success message saying that an activation link has been dispatched, please check your email to activate you account and then login. You will go to your inbox and you might try refreshing the page once or twice and then you would find the email !!. So there is a small delay in receiving the activation email after registration, isn’t it ?

What happens behind the scenes ?

First the web form data get saved to database after validation. If everything is fine then the data will be saved to database along with the generated activation link. Then activation will be sent to you email. Here the sending email part typically takes around let’s 10 seconds. Provided that there is only one mail server, if suppose 100 people are registering at the same time, the 100th person may have to wait at least 99*10 seconds, i.e woofing 16 minutes to see the success message !!

Can you image without threads how we can solve this problem !!

So what we do is we will separate the code responsible for sending the email to run in another thread which will be queued and user will be able to see the success message in web page instantly but email sending will be happening in background. Because of this reason, sometimes you notice the delay in receiving the confirmation email.

Let take a more realistic example.

video

Please write down the example program as it is in the above video and then continue writing below notes 🙂

As we can see in the above program Task 4 and Task 5 has got no dependency on task 3 ( sorting task ) to yet they have to wait. We can simple separate the time consuming task like this to run in separate thread.

Before we go further and start creating the thread, let’s first just define what exactly is a thread ?

In fact when we say thread in Java it means two things.

  • An instance of class java.lang.Thread
  • A thread of execution

Everything is objects in Java. Same way a thread is also in object like any other objects. It has got it variables & methods, and lives and dies on the heap just like any other object.

But a thread of execution is an individual process that has its own call stack. A thread can be called as a “lightweight” process that has it’s own call stack. In fact there is one call stack exactly one each thread.

We been already using threads !!, remember our main() method – the starting point !!. It’s actually the main thread in execution. This is where everything starts. As soon as you create a thread in main, a new stack get formed and methods called within that thread pushed into the new stack created which is separate from the main stack or main methods. That’s why we call it individual process, they are totally become independent they even will not have any idea it main thread is still alive or dead but there is a way to check if a thread is alive or not.


Two ways of Creating a Thread in Java

  1. By implementing Runnable interface
  2. By extending class Thread

Either way you do it but ultimately you need to have an instance of java.lang.Thread class.

1.  By implementing Runnable interface

Compare to 2 way of doing it’s quite difficult so unlike other authors I am going to teach you the difficult one first 😨. You will thank me later 🙂

video

Step1 : Create a class which implements Runnable interface

Step2: Override run() method and place the code inside run() which you want to run in separate thread.

Step3: Create an instance of the class which implements Runnable interface.

Step4: Create an instance of java.lang.Thread class using a constructor which has got a parameter of type Runnable, where send the instance you created in step3 as argument to the Thread constructor.

Step5: Call start() method through the instance of Tread which we created in Step4.

video

start() method of Thread class has got internal implementation to pick up the code present in run() method and run it seperate thread.

Step by step notes to be narrated in class about the steps taken in the above video and then the example.

2. By extending class Thread

video

Step1 : Create a class which extends class Thread.

Step2: Override run() method and place the code inside run() which you want to run in separate thread.

Step3: Create an instance of the class which extends class Thread.

Step4: Call start() method through the instance of Tread which we created in Step3.

Important note : You may think that extending the class Thread is the best way you found it easier to create thread but it’s not a good OO practice as there will be no scope for extending another class in future & if it’s required to extend some other class in future then program will go through radical changes.

I hope you notice that run() & start() methods has got no arguments !!

OMG !!how do I send some data as input a to a thread then !! Give some work to your brain 🙂 , I will answer that sometime later.


Multi-threading

video

As you can see in the above example ( program in video ), everytime we execute the program we get different order of output. When it comes to multithreading order of threads execution is not guaranteed except

“Each thread will start, and each thread will run to completion.”

Within each thread things will happen in predictable manner ( obviously; because it’s just executing the set of instruction in run() method) but action of different threads can mix up in unpredictable way. If you run in multiple times or on multiple machines, you may see different output.

Because we start good first, bad next and then ugly it doesn’t mean that they will start or execute in that order only.

The reason for all this is because of a program called Thread Scheduler which we study in next lesson.

Once the thread had been started it can not be started again.

Multithreading Example with Common resource :

package com.felight.corejava.threads;
public class MultithreadingWithCommonResource {

    public  void doSomething(){
        Thread currentThread = Thread.currentThread();
        for(int i=0; i<5; i++){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(currentThread.getName() + " " + i);
        }
    }

    public static void main(String[] args) {
        MultithreadingWithCommonResource obj = new MultithreadingWithCommonResource();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                obj.doSomething();
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                obj.doSomething();
            }
        });

        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                obj.doSomething();
            }
        });

        t1.setName("t1");
        t2.setName("t2");
        t3.setName("t3");

        t1.start();
        t2.start();
        t3.start();

    }
}

Thread Scheduler & Thread Life Cycle

 The Thread Scheduler :

video

The Thread Scheduler is part of JVM which decides which thread to run at any given point of time. All most all JVMs maps java threads to operating systems native threads. We do not have any control over it but how ever few methods in java.lang.Thread class can help us in influencing the thread schedule.

The algorithm used by Thread Scheduler program is never known to us the there is no way to predict it. It varies from system to system, jvm to jvm, version to version. In fact in same system just from time to time we will not be able to predict how scheduler works.

The order in which runnable threads are chosen to run is not guaranteed however when a thread finishes it’s turn it moves to the end of the line of runnable pool , perhaps we can call it as runnable queue. Since we don’t control the Thread Scheduler we don’t know which one scheduler will choose. We can influence it by using some methods present in Thread class like setPriority() but be caution that influsing is not controlling. I may influence an Employer that you are my best student and please consider this candidate but it’s only a influence and I am not in control of Employer.

Some of the methods that can help us influence thread scheduling are :

in Thread Class :

public static void sleep(long millis) throws InterruptedException
public static yield()
public final void join() throws InterruptedException
public final void setPriority(int newPriority)

Note that sleep() and join() methods have got other overloaded versions which I haven’t listed here.

in Object class :

public final void wait() throws InterruptedException
public final void notify()
public final void notifyAll()

Note that wait() method have got 3 overloaded versions including the the listed above.

Thread Lifecycle ( Thread State and Transitions ) :

  1. New: The moment new instantiate class Thread we can say that thread has entered new state but before calling start() method. At this point thread is considered alive. You can call isAlive() method to ensure it.
  2. Runnable : Thread enters this state when we call start() method but schedule has not selected it to be the running thread. A thread can come to runnable stage from running state directly by calling yield() method. A thread can come to runnable state from a stage called Waiting/Blocked/Sleeping. A Schedular will choose a thread to run only from Runnable stage so a thread has to come to Runnable stage for scheduler to select it.
  3. Running : Thread is executing. This where the real work is happening. Thread enters this state when schedule select a thread from Runnable state to run. From Running state it can go to Sleeping state by calling sleep method, it can enter Blocked state if scheduler blocks it when it tries to access any synchronized resource.
  4. Waiting/Blocked/Sleeping : Thread is alive but not running. This is the state the thread is in when it’s not eligible to run. This is really three states combined into one but they all have one thing in common i.e  thread is still alive but not eligible to run. From this state thread will go to Runnable state and the process continues. If the Thread enters this state by calling sleep() method then a wake up event will send the thread to Runnable state after the sleep time is expired. Scheduler moves a thread to Blocked state when the thread accesses a synchronized resource which eventually notified on a resource release event, and then thread enters Runnable state. We discussed about how a thread enters waiting earlier. hmm so much explanation isn’t it !! 😅.
  5. Dead : A Thread which is no longer alive. Any thread will reach this state once it completes the execution of all the codes inside run() method. Once a thread is dead it means dead, that’s it, it can not become alive again. It’s not a pirates of carribean movie where Captain Jack sparrow was brought back to life from the land of the dead😲.
Important Note: In past, when you were looking at your dad mom and trying to walk like a man using your two legs with that beautiful smile, those pretty eyes, Java developers decided to stop the development of resume(), suspend(), and stop() methods of Thread class. i.e in JDK 1.1 :-). The reason is because there is no safe way to stop a thread or resume or to suspend. Even after 20 years they those methods are still deprecated.  And in the video lesson why said don’t ever say that there is no stop() method to stop a thread because, so many JAVA developers are not aware of the fact that it was introduced in JDK but they have been deprecated 20 years back.

Thread Life Cycle

Thread Life Cycle :


How you can prevent Thread Execution ?

Using following behaviour or event we can prevent a thread execution

  • Sleeping
  • Waiting
  • Blocked because it needs an object’s lock

Making a Thread Sleep :

Why do we need to make to thread to go to sleep ?. Let’s say your thread requesting server for information continuously which will consume lots of resource and bandwidth. You might want to limit this thread to request for new information once in 10 minutes. How do you make a thread to sleep for 10 minutes before it comes back to runnable state ?. Like I shown you in Multithreading example, you just have to call the sleep() static method in Thread class which imposes the current thread to sleep for specified amount of time.

Note: sleep() is a static method of class Thead. Notice that sleep() method can throw a checked InterruptedException, so it should be anticipated which calling. When we call the sleep() method the thread goes to sleeping state but when it wakes up it has to come to Runnable state only.


Thread Priorities and yield()

Thread Priorities and yield() :

To understand yield(), you must understand the concept of thread thread priorities. Thread always runs with some priority which can be from 1 to 10. Child thread gets the same priority as parent which we can change after the thread is created by calling setPriority() method. The default priority is 5, so is the Main Thread priority. Highest value indicated the highest priority but be aware that the Thread Scheduler program in many JVM uses preemptive, priority-based scheduling but it doesn’t mean that all JVMs will do the same.

In most JVM the Scheduler does use thread priorities i.e if there are two threads in Runnable state with the priority 9 & respectively then the scheduler  will choose the thread with the priority 9 first, having said that it’s not always true and you can not ever really predict it and setting the priority will not really allow us the control the thread execution order. In most cases the current running thread will have the equal or highest priority compared the threads the runnable pool.

The yield() Method :

static Thread.yield() method is supposed to make the current running thread head back to Runnable state to allow other threads of equal priority to get their turn but in reality, the yield() method isn’t guaranteed to what it claims, and even suppose if it does the job of making a thread to head back to Runnable state it doesn’t mean that scheduler will choose other thread with equal priority !! because it a independent program which is unpredictable as we know it.

A yield() method won’t ever cause a thread to go to waiting/sleeping/blocking state.

package com.felight.corejava.threads;

/**
 * Created by Vinay Noah
 * For The Best Online Training with quick professional
 * developer support visit www.felight.io
 *

* For 100% Job Assured Java Training visit http://www.felight.com * youtube.com/felight * +91 96116 96116, +91 9611406060 */ public class YieldDemo implements Runnable{ Thread t; YieldDemo(String str) { t = new Thread(this, str); // this will call run() function t.start(); } public void run() { for (int i = 0; i < 5; i++) { // yields control to another thread every 5 iterations if ((i % 5) == 0) { System.out.println(Thread.currentThread().getName() + “yielding control…”); /* causes the currently executing thread object to temporarily pause and allow other threads to execute */ Thread.yield(); } } System.out.println(Thread.currentThread().getName() + ” has finished executing”); } public static void main(String[] args) { new YieldDemo(“Thread 1”); new YieldDemo(“Thread 2”); new YieldDemo(“Thread 3”); } }


The join() Method

The join() Method :

The non-static join() method of class Thead lets one thread “join onto the end” of another thread. Where it is useful ? Suppose if a have a thread t2 which can not start its work until t1 is complete !! that’s when we make use of join(). It means that t2 can not become runnable unless t1 is dead.

Example:

package com.felight.corejava.threads;

/**
 * Created by Vinay Noah
 * For The Best Online Training with quick professional
 * developer support visit www.felight.io
 *

* For 100% Job Assured Java Training visit http://www.felight.com * youtube.com/felight * +91 96116 96116, +91 9611406060 */ public class JoinDemo implements Runnable { @Override public void run() { Thread t = Thread.currentThread(); System.out.println(“Thread started: “+t.getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(“Thread ended: “+t.getName()); } public static void main(String[] args) { Thread t1 = new Thread(new JoinDemo(), “t1”); Thread t2 = new Thread(new JoinDemo(), “t2”); Thread t3 = new Thread(new JoinDemo(), “t3”); t1.start(); //This will start t1 immediately //below statement makes sure that //t2 will start only after t1 is dead try { t1.join(); } catch (InterruptedException e) { e.printStackTrace(); } t2.start(); //below statement makes sure that //t3 will start only after t1 & t2 is dead try { t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } t3.start(); } }


Synchronizing a Resource

video

Just imagine a banking scenario. Let’s say you got $25,000 balance in your bank account. You will initiate an online funds transfer of 25K to your other bank account and at the same time you go to ATM and try to withdraw 25K. They both are basically two threads which will call the resource called getBalance() before they can go further and initiate the transfer. If these two threads call the method getBalance() at the same time, hypothetically speaking bank end up paying 50K to you, I can see the smile in your face :-). Happy !!

So lets solve this problem as a real developer and help bank to estiguesh this problem. All we have to do is, just synchronize the resource so that if one thread locks the resource then another thread has to wait till the resource is released.

Example:

package com.felight.corejava.threads;



    public class BankAccount {

        public synchronized static void getBalance(){
            Thread currentThread = Thread.currentThread();
            for(int i=0; i<5; i++){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                System.out.println(currentThread.getName() + " " + i);
            }
        }

    }
package com.felight.corejava.threads;


public class SyncDemo {

    public static void main(String[] args) {

        Thread atm = new Thread(new Runnable() {
            @Override
            public void run() {
                BankAccount.getBalance();
            }
        });

        Thread online = new Thread(new Runnable() {
            @Override
            public void run() {
                BankAccount.getBalance();
            }
        });


        atm.setName("ATM Thread");
        online.setName("Online Thread");


        atm.start();
        online.start();

    }

}

In the above example I intentionally made the getBalance() method as static so that two thread can access the common shared resource to illustrate the use of synchronized keyword.

Try removing the synchronized keyword of getBalance() method and see for yourself 🙂

How does the Synchronization works ?

It’s pure luck, just kidding its lock. Every object in Java has a built-in lock that only comes into play when the object has a synchronized method code.

When we enter a synchronized non-static method, we automatically acquire the lock  associated with the current instance of the class which is in execution( this ).

Acquiring a lock for an object is also known as

  • getting a lock or
  • locking the object or
  • locking on the object or
  • synchronization on the object

Some people use the term monitor to refer to the object whose lock we are acquiring but technically, the lock and monitor are two different things however most people talk about the two interchangeably, and we will also do the same.

Since there is only one lock per object, if one thread has picked up the lock, no other thread can pick up the lock until the first thread release the lock. This means no other thread can enter the synchronized code ( method of that object ) until lock has been released.

Typically, releasing the lock means the thread holding the lock exits the synchronized method on that object.

Key points and locking and synchronization :

  • Only methods ( or blocks ) can be synchronized, not variables or classes.
  • Each object just has one lock.
  • It’s not necessary that all the methods in a class should be synchronized. A class can have both synchronized and non syncronized methods.
  • If two threads are about to execute a synchronized method in a class and both threads are using the same instance of the class to invoke the method then only one thread at a time will be able to execute the method. The other thread need to wait until the first one finishes its method call.
  • If a class has got both synchronized and non syncronized methods then multiple thread can still access the non synchronized methods.
  • Synchronization can cause a hit in some cases or even deadlock if used incorrectly, so you my friend, should be very careful not to overuse it. For example let’s say you made a thread sleep for a long time but if it was in between execution of a synchronized method( or block) then obvious it will not release it. We can say a resource is released when thread exits from that method, isn’t it ? What you make of this situation.
  • A thread can acquire more than one lock. For example, lets say thread entered synchronize block in which a call to another synchronized method is made, in this case as stack unwinds, locks are released.
  • You can synchronize a block of code rather than a method.

You should not synchronize more than what is necessary as it will affect the overall performance. Let’s say you got many statements in a method and you want only few statements to be synchronized then you can use synchronized blocks.

Example :

 public void doSomething(){

        System.out.println("Statement 1");
        System.out.println("Statement 2");
        synchronized (this){
            System.out.println("Statement 3");
        }

        System.out.println("Statement 4");
        System.out.println("Statement 5");

    }

What that this in the above example ?

We have tell lock on what isn’t it ? So it can be another instance if you wish. this points to current object to the lock on upon current object itself.

Can Static Methods Be Synchronized ?

Yes, static methods can be synchronized. There will be only one copy of static data we are trying to protect, we just need one lock per class to synchronize the static methods. Actually there is such a lock, every class loaded in Java has a corresponding instance of java.land.Class representing that class.

Our first example was a static method isn’t it ?

static method synchronization real world example

public static synchronized void incrementNoOfViews(){
    noOfViews++;
}

above method can be replaced with synchronized block.

public class SynchronizedBlocks {

    static int noOfViews;

    

    public static synchronized void incrementNoOfViews(){
        synchronized (SynchronizedBlocks.class){
            noOfViews++;
        }
        
    }
.
.
.

in the above example SynchronizedBlocks.class is just a class literal. It’s the special feature of Java which tell the JVM to go and find the instance of Class that represent the class called SynchronizedBlocks. Same example can be rewritten as below.

public class SynchronizedBlocks {

    static int noOfViews;


    public static synchronized void incrementNoOfViews() throws ClassNotFoundException{
        Class instanceOfSynchronizedBlocks = Class.forName("com.felight.corejava.threads.SynchronizedBlocks");
        synchronized (instanceOfSynchronizedBlocks) {
            noOfViews++;
        }
    }
}

What Happens If a Thread Can’t Get the Lock?

If a thread try to access a method and its already locked then thread is said to be blocked state. There could possibility that more thread are already in blocked state for the same method, isn’t it ?. In this case they are said to be in a kind of pool, for the particular object and threads has to sit there until the lock is released. The thread which is been waiting for a long time will be the first to get the lock after lock is release by a thread for the particular object.


Thread-Safe Classes

When the methods are carefully synchronized and data has been protected in a class we can say that the class is thread safe. Remember that in Strings chapter I told you that StringBuffer is a thread safe where is StringBuilder is a clone of StringBuffer but it’s not thread safe. Save way Vector class of collection is thread safe where the other counterpart ArrayList API is not thread safe, which only means that the methods of those classes are synchronized.


Thread Deadlock

Welcome to Hell. This is worst nightmare that Java developers could ever have, even in the interviews. So I spent enough time to make it easy so that you can sleep well 🙂

Thread Deadlock occurs when two threads are blocked and each waiting for other’s lock. Neither can run unless other release the lock so they will be in blocked state forever. It’s the typical situation of a businessman. To start business you need money and to earn money you need to start business :-).

Another real world example : To get a Job you need experience, to get experience you need a Job :-). World sometimes looks cruel isn’t it !!.

package com.felight.corejava.threads;

/**
 * Created by Vinay Noah
 * For The Best Online Training with quick professional
 * developer support visit www.felight.io
 *

* For 100% Job Assured Java Training visit http://www.felight.com * youtube.com/felight * +91 96116 96116, +91 9611406060 */ public class ThreadDeadlockDemo { String str1 = “I love you”; String str2 = “I love if you love me”; Thread trd1 = new Thread(“My Thread 1”){ public void run(){ while(true){ synchronized(str1){ synchronized(str2){ System.out.println(str1 + str2); } } } } }; Thread trd2 = new Thread(“My Thread 2”){ public void run(){ while(true){ synchronized(str2){ synchronized(str1){ System.out.println(str2 + str1); } } } } }; public static void main(String a[]){ ThreadDeadlockDemo threadDeadlockDemo = new ThreadDeadlockDemo(); threadDeadlockDemo.trd1.start(); threadDeadlockDemo.trd2.start(); } }

If you run the above program it will keep going on forever as they both have dependency on each others lock.


Thread Interaction

Finally we reached the very last chapter of threads. If you have understood all the previous lessons very well then it was nothing less than a hollywood blockbuster thriller movie, isn’t it?

How does the threads can communicate with other threads ?

The Object class has three methods, wait(), notify(), and notifyAll(), that help threads communicate the status of an event that the threads care about.

Let’s say one thread is doing the job of capturing an image and another thread is responsible for processing the image and convert color image to gray scale. The first thread should tell the second thread that I have completed my work and now you can carry on your processing Job. This can be achieved using wait() and notify() methods. Suppose if there are multiple threads where one does the Job of converting image to grayscale and other does the Job of resizing the image and one more thread does the job of mailing the captured raw image to someone. In this case notifyAll() comes into picture.

Important Note : One important thing is that you should always call wait(), notify(), and notifyAll() methods from a synchronized context.


Overriding hashcode() & equals()

equals() method

You remember we used == operator to compare two strings objects i.e str1==str4, which resulted in false even though they both had the value “Felight”. We studied there that comparing two objects like that result in false because they are two different references which are pointing to two different objects. And later we compared their values using equals() method i.e. str1.equals(str4) which returns false.

In last lesson of inheritance chapter we also studied that equals() method is first defined in Object class which we can override if we wish. But that particular lesson focus was on toString() method.

It’s clearly evident that java.lang.String class has overridden the equals method to return true after comparing the contents of the object and return false if the contents are not same. Not only equals() method, String API also provide one more extra method to compare the values of object by ignoring the case i.e equalsIgnoreCase().

Same way suppose if we wish to compare the contents of the instances of our classes then we should override equals method and compare the datamember in it and return true if the contain the same data.

Lets understand it with an Example.

veoid

Please pause the video when ever u wish and note down the equals() method implementation of  Employee class for your reference 🙂

 

Note: You can not simple jump into the implementation of equals() method as you wish. You should follow the correct Java contract specified in Java API spec.

A Java contract is a set of rules to be followed.

It’s something I followed in the equals() method of Employee class. We could have jumped straight away to cast obj to Employee but first we checked if obj is instanceOf Employee and that what Java Contract saysin in Java API spec.

Why don’t we just create a method called

public boolean equals(Employee emp) directly !!?

Yes, ofcourse it possible in that case it will be an overloaded method not overridden. So there will be two methods with the same name but difference is in the type of parameter. One expects the instance of Object class and other accepts the instance of Employee and many APIs in Collections Framework will call the equals() method with the parameter of type Object class.

 

hashcode() method

equals() and hashcode() methods joint Java contract has a rule that if two object are considered as equal using the equals() method, then they should contain same hashcode values.

Why Java developers made it like that ? In order the understand first we need to understand what exactly is a hashcode of an Object ?

You could say it more like an id number of an Object but not necessarily has to be unique. Using this HashMap, HashSet apis store the objects in Collection.

Let’s understand more about it with this below example.

video

So as thumb rule remember that if you override equals() method then you should hashcode() method.

Let’s do that in our Employee class.

video

Above example may not be the best implementation of hashcode() method but this will do as the hashcode() method is returning the identical values to the object which are considered as equal by equals() method.

consider the below scenario

Suppose if we have above implementation of hashcode() method  in Employee class then the hashcode all all Employee objects will be same. It’s still valid but conceptually wrong.

Hashcode are typically used to increase the performance of large collections of data. Hashcode value of objects are extensively used by many APIs present in Collections Framework, specially HashMap, HashSet, HashTable most of these APIs name starts with Hash. These APIs relay upon hashcode value of an Object to store the object in Collection.

This much explanation is more than enough to crack any interview on this topic or even to crack OCA/OCP exam (formerly known as OCJP ).

Now it’s time to start with actual Collections chapter.