Thread and Multithreading in Java for beginners (Part 1)

This will be a series on threads and Multithreading in java . I will demonstrate all the concepts and program for Multithreading in java which will be very beneficial for the people who are just starting.

What is thread?
A thread is a part of a process.A process can contain multiple threads
What is Multithreading?
the idea is to achieve parallelism by dividing a process into multiple process.

How to create a basic program of threads in Java?
There are two ways to do this

  1. By Extending the thread class ( I prefer this method )
public class ThreadMainAnotherMethod {
    public static void main(String[] args) {
        Thread thread = new NewThread();
        thread.start();
    }

    public static class NewThread extends Thread {
        @Override
        public void run() {
       	     System.out.println(" NewThread has been started " + this.getName());
        }
    }
}
// Output : NewThread has been started Thread-0

2. By using Runnable Interface

public class ThreadMain {
    public static void main(String[] args) throws InterruptedException {

        Thread thread1 =  new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("The name of the Thread is " + Thread.currentThread().getName());
            }
        }) ;
	  thread1.start();
      }
  }
// Output : The name of the Thread is Thread-0

We can setName , setPriority of the thread as per requirements:

public class ThreadMain {
    public static void main(String[] args) throws InterruptedException {

        Thread thread1 =  new Thread(new Runnable() {
            @Override
            public void run() {
               System.out.println("Currently the name of the Thread is " + Thread.currentThread().getName());

            }
        }) ;
        thread1.setName("ThreadCool");
        thread1.setPriority(Thread.MAX_PRIORITY);
        System.out.println("Before Starting the thread , name is : " + Thread.currentThread().getName());
        thread1.start();
      }
  }

Catching Exceptions in thread Examples:

public class sample {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                throw new RuntimeException("Internal Exception");
            }
        });
        thread.setName("Exception Example");
        thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread t, Throwable e) {
                System.out.println("A critical Exception has been thrown " + t.getStackTrace());

            }
        });
        thread.start();
    }
}

//Output : A critical Exception has been thrown [Ljava.lang.StackTraceElement;@334a1cfd

Simple Application

There are two hackers which are trying to hack a system and there is a policeman who want to catch them.
Policeman ha exactly ten seconds before the location of the hacker can be tracked.The Program is given below:

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class HackerPoliceApplication {
    public static void main(String[] args) {
        Random random = new Random();

        Vault vault = new Vault(random.nextInt(9999));

        List<Thread> threads = new ArrayList<>();

        threads.add(new AscendingHackerThread(vault));
        threads.add(new DescendingHackerThread(vault));
        threads.add(new PoliceThread());             //Application of polymorphism

        for (Thread thread : threads) {
            thread.start();
        }
    }


     //class which stores the correct password for the system
     private static class Vault {
        private int password;

        public Vault(int password) {
            this.password = password;
        }

        public boolean isCorrectPassword(int guess) {
            try {
                Thread.sleep(5);
            } catch (InterruptedException e) {
            }
            return this.password == guess;
        }
    }
    
    //The class which will be extended by two hackers
    private static abstract class HackerThread extends Thread {
        protected Vault vault;

        public HackerThread(Vault vault) {
            this.vault = vault;
            this.setName(this.getClass().getSimpleName());
            this.setPriority(Thread.MAX_PRIORITY);
        }

        @Override
        public void start() {
            System.out.println("Starting thread " + this.getName());
            super.start();
        }
    }

    //Below two class extends the HackerThread and then try to hack the system
    private static class AscendingHackerThread extends HackerThread {

        public AscendingHackerThread(Vault vault) {
            super(vault);
        }

        @Override
        public void run() {
            for (int guess = 0; guess < 9999; guess++) {
                if (vault.isCorrectPassword(guess)) {
                    System.out.println(this.getName() + " guessed the password " + guess);
                    System.exit(0);
                }
            }
        }
    }

    private static class DescendingHackerThread extends HackerThread {

        public DescendingHackerThread(Vault vault) {
            super(vault);
        }

        @Override
        public void run() {
            for (int guess = 9999; guess >= 0; guess--) {
                if (vault.isCorrectPassword(guess)) {
                    System.out.println(this.getName() + " guessed the password " + guess);
                    System.exit(0);
                }
            }
        }
    }

    //Police thread which will count for 10 secs
    private static class PoliceThread extends Thread {

        @Override
        public void run() {
            for (int i = 10; i > 0; i--) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
                System.out.println(i);
            }
            System.out.println("Game over for you hackers");
            System.exit(0);
        }
    }
}
//Output : ***Output maybe different for everyone***

//Starting thread AscendingHackerThread
//Starting thread DescendingHackerThread
//10
//9
//8
//7
//6
//5
//4
//3
//AscendingHackerThread guessed the password 1493