DEV Community

vikash-agrawal
vikash-agrawal

Posted on • Updated on

Multi Threading In Java

Thread Lifecycle in java

Once a thread completes its execution, it reaches to Dead state that means the given thread cannot be started again, means you can’t invoke start method more than once.
The join() method waits for a thread to die. In other words, it causes the currently running threads to stop executing until the thread it joins with completes its task.

class TestJoinMethod1 extends Thread{  
 public void run(){   
  for(int i=1;i<=5;i++){  
   try{  
    Thread.sleep(500);  
   }catch(Exception e)
   {
    System.out.println(e);
   }  
  System.out.println(i);  
  }  
 }  

 public static void main(String args[]){  
  TestJoinMethod1 t1=new TestJoinMethod1();  
  TestJoinMethod1 t2=new TestJoinMethod1();  
  TestJoinMethod1 t3=new TestJoinMethod1();  
  t1.start();  
  try{   
   t1.join();  
  }catch(Exception e)
  {
   System.out.println(e);
  }   

 t2.start();  
 t3.start();  
}  
}  
Enter fullscreen mode Exit fullscreen mode

Output:1 2 3 4 5 1 1 2 2 3 3 4 4 5 5

Main thread will wait for all the user threads to complete then will exit.
If there are no user threads are running then daemon thread will also die.

ThreadPool

  public class TestThreadPool {  
     public static void main(String[] args) {  
        ExecutorService executor = Executors.newFixedThreadPool(5);//creating a pool of 5 threads  
        for (int i = 0; i < 10; i++) {  
            Runnable worker = new WorkerThread("" + i);  
            executor.execute(worker);//calling execute method of ExecutorService  
        }  
        executor.shutdown();  
        while (!executor.isTerminated()) {   }  

        System.out.println("Finished all threads");  
    }  
 }
Enter fullscreen mode Exit fullscreen mode

Output

pool-1-thread-1 (Start) message = 0
pool-1-thread-2 (Start) message = 1
pool-1-thread-3 (Start) message = 2
pool-1-thread-5 (Start) message = 4
pool-1-thread-4 (Start) message = 3
pool-1-thread-2 (End)
pool-1-thread-2 (Start) message = 5
pool-1-thread-1 (End)
pool-1-thread-1 (Start) message = 6
pool-1-thread-3 (End)
pool-1-thread-3 (Start) message = 7
pool-1-thread-4 (End)
pool-1-thread-4 (Start) message = 8
pool-1-thread-5 (End)
pool-1-thread-5 (Start) message = 9
pool-1-thread-2 (End)
pool-1-thread-1 (End)
pool-1-thread-4 (End)
pool-1-thread-3 (End)
pool-1-thread-5 (End)
Finished all threads
Enter fullscreen mode Exit fullscreen mode

Wait-notify

package com.learnings.synch;

public class Tutorial {
   private static Account account = new Account();

   public static void main(String[] args) {
       Thread[] depositThreads = new Thread[5];
       Thread[] withdrawThreads = new Thread[8];
       for (int i = 0; i < 5; i++) {
           depositThreads[i] = new Thread(new UserThread(account, "deposit"));
       }
       for (int i = 0; i < 8; i++) {
           withdrawThreads[i] = new Thread(new UserThread(account, "withdraw"));
       }
       for (Thread thread : withdrawThreads) {
           thread.start();
       }
       try {
           Thread.sleep(5000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       for (Thread thread : depositThreads) {
           thread.start();
       }

   }
}

/**
*
*/
package com.learnings.synch;

/**
* @author Vikash Agrawal 
*
*/
public class Account {
   private int balance = 50;
   private Object lock = new Object();

   private void withdraw(int amount) {
       balance = balance - amount;
   }

   private void deposit(int amount) {
       balance = balance + amount;
   }

   public int getBalance() {
       return balance;
   }

   public void deposit() {
       synchronized (lock) {
           System.out.println("Will be deposited by: " + Thread.currentThread().getName());
           deposit(10);
           lock.notify();
           System.out.println("After deposit: " + getBalance());
       }
   }

   public void withdraw() {
       synchronized (lock) {
           System.out.println("Will be withdrawn by: " + Thread.currentThread().getName());
           if(getBalance() < 10) {
               try {
                   lock.wait();
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
           withdraw(10);
           System.out.println("After withdraw: " + getBalance());
       }
   }
}

/**
*
*/
package com.learnings.synch;

/**
* @author Vikash Agrawal 
*
*/
public class UserThread implements Runnable {
   private String operation;
   private Account account;

   public UserThread(Account account, String operation) {
       this.account = account;
       this.operation = operation;
   }

   public void run() {
       switch (operation) {
       case "deposit":
           account.deposit();
           break;
       case "withdraw":
           account.withdraw();
           break;
       }
   }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
sohamraje137 profile image
Soham Patil

It would be better to make
Void deposit(int) and void withdraw (int) private methods, right?