What is Method Overloading?

Method Overloading:

One or more methods  in a class having same name, but different number or type of arguments, is called method overloading.

When a overloaded method is called, the method with matching number and type of arguments gets executed.

If there is no exact match of argument types, type promotion is applied, before invoking the method.

For eg

class Abc{

void add(int i, int j){  //body of method }

void add(float i, float j, float k){ //body of method }

void add(int i,int j, int k){ //body of method }

}

NOTE:

1.Method overloading cannot be done, based only on return type of the method

2.Method overloading is compile time polymorphism, as the method which need to get called is decided/binded during compile time itself.

Question:

Can below methods be overloaded??

class Abc{

void add(int i, int j){  //body of method }

int add(int a, int b){ //body of method }

}

How to set or change priority of Main Thread?

As already specified, you need to use setPriority() and getPriority() methods of Thread class to change and to retrieve priority of a Thread. However, first we need to get the Thread object of main Thread. This can be achieved using Thread.getCurrentThread(), which returns Thread object of the current Thread. Below is snippet of code

public class MainThreadPriority {
	public static void main(String[] args) {
		Thread t = Thread.currentThread();
		
		System.out.println("Priority of "+t.getName()+" thread is: "+t.getPriority());
		
		t.setPriority(Thread.MAX_PRIORITY - 2);
		
		System.out.println("Now, Priority of "+t.getName()+" thread is: "+t.getPriority());
	}
}

You may also like to read:
All Threads examples

purpose of wait() and notify() methods in Object class

As briefed in all methods of Object class these methods are final and defined in java.lang.Object class. Hence these methods are available in each and every class, because Object class is base class of all classes, in Java. These methods can be invoked only from synchronized block or synchronized method.
wait(); – It tells the calling thread to give up the lock and go to sleep until some other thread calls notify() method on same object.
notify(); -It wakes up one single thread that called wait() on the same object.
notifyAll(); – It wakes up all the threads that called wait() on the same object.
These methods can be used to solve producer consumer related problems.

Below is simple example in which Main thread invokes wait() on threadb, after threadb computes total sum, it invokes notify() method, so that Main thread gets the control, and prints total value.

public class NotifyWait {
	public static void main(String[] args) {
		NotifyWaitB b = new NotifyWaitB();
		b.start();
			synchronized(b){
			try{
				System.out.println("A:waiting for b thread to complete...");
				b.wait();
			}catch(Exception e) {
				System.out.println("Interrupted Exception:"+e.getMessage());
				//e.printStackTrace();
			}		
			System.out.println("Total is:"+b.total);
		}
	}
}


class NotifyWaitB extends Thread{
	int total;	
	public void run(){		
		System.out.println("in run() method of Child thread");
		synchronized(this)
		{
			for(int i=0;i<30;i++)
			{
				total += i;				
			}			
			notify();
			System.out.println("notify() invoked from Child thread");
		}		
	}
}

Below is some real time example on using wait() and notify() methods.

wait-notify-notifyall-example
wait-notify-notifyall-example

Here Display Thread, need to continuously check(with a infinite loop or so) Packet Queue, to find if new Packets are available, which may not be a professional approach. As continuously checking Packet Queue, may waste CPU time, and may adversely affect performance of overall Application. This problem can be solved better, by using wait() and notify(). Below are the steps involved…

Downloader Thread downloads packets, adds to Queue.
Calls notify() method on Queue, which wakes up Display Thread.

Now display Thread reads packets from Queue, processes them.
Calls wait() method on Queue, which goes on sleep, until notify() is called by Downloader Thread.

You may also like to read:
how to use join() method between child threads?
how to avoid deadlock in threads
can a child thread start another child thread?

Can Thread join() be used between two child Threads

Refer purpose of join method in multi threading , for basic details on join() method. Generally a parent Thread invokes join() method on one or more child threads, that means parent thread gets suspended, until its one or more of its child threads completes execution. As shown in below example it is possible to use join() method between child threads as well.


class ThreadA extends Thread
{
	public void run(){
		for(int i=0;i<10;i++)
		{
			try{
			System.out.println("ThreadA:"+i);
			Thread.sleep(1000);
			}catch(Exception et)
			{
				System.out.println(et);
			}
		}
	}
}

class ThreadB extends Thread
{
	public void run(){
		System.out.println("run() in ThreadB");
		try{
		JoinBetweenChildThreads.ta.join();
		
		for(int i=20;i<30;i++)
		{
			System.out.println("ThreadB:"+i);
			Thread.sleep(1000);
		}	
		}catch(Exception et){ System.out.println(et); }
	}
}

public class JoinBetweenChildThreads {
	static ThreadA ta;
	static ThreadB tb;
	
	public static void main(String[] args) {
		ta = new ThreadA();
		tb = new ThreadB();
		
		ta.start();
		tb.start();
	}
}

How to Serialize an array or Collection of objects

Hope you have already gone thru basic working of Serialization. To Serialize an array of objects of a class, below are the steps.
1. The class whose array of objects need to be serialized, has to implement java.io.Serializable interface
2. Create another class, which has an array or Collection of objects, as a data member. This class also has to implement Serializable interface.
3. Now, you can follow normal steps to Serialize class created in above, step2

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package javaapplication2;

import java.io.Serializable;

class StudentInfo implements Serializable
{
 //transient data members will not take part in Serialization   
 String name;
int rid;
 StudentInfo(String n, int r)
 {
  this.name = n;
  this.rid = r;
 }

 void printStudentInfo()
 {
     System.out.println("StudentInfo details Test:"+name+" "+rid+" ");
 }
 
 public String toString()
 {
     return "name="+name+", id="+rid;
 }
}


class StudentInfoArray implements Serializable{
    StudentInfo arr[];
    
    StudentInfoArray(StudentInfo arr[])
    {
        this.arr = arr;
    }
}
package javaapplication2;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SerializeArray
{
    
 public static void main(String[] args)
 {
 try
 {
//Serialization starts here
  StudentInfo si1 = new StudentInfo("checkingnexttime", 310);
  
  StudentInfo si2 = new StudentInfo("checkingnexttime1", 311);
  
  StudentInfo si3 = new StudentInfo("checkingnexttime2", 312);
  
  StudentInfo sarr[] = {si1, si2, si3};
  
  StudentInfoArray sia = new StudentInfoArray(sarr);
  
  //.ser is a standard file extension, to store serialized object
  FileOutputStream fos = new FileOutputStream("C:\\student.ser");

  //instead of writing object stream to a file, it is also possible to send object thru 
  //Network using socket programming
  ObjectOutputStream oos = new ObjectOutputStream(fos);

  System.out.println("Serialing the object...");
  oos.writeObject(sia);
  oos.close();
  fos.close();  
  }
  catch (Exception e)
  { e. printStackTrace(); }
 }
}
package javaapplication2;

import java.io.*;

public class DeSerializeArray {
 public static void main(String[] args)
 {
 try
 {
  
  System.out.println("De serializing object...");
  //DeSerialization starts here
  FileInputStream fis = new FileInputStream("C:\\student.ser");
  ObjectInputStream ois = new ObjectInputStream(fis);
  StudentInfoArray toa = (StudentInfoArray)ois.readObject();

  System.out.println("before printing Object");

  for(StudentInfo si:toa.arr)//foreach
  {
      System.out.println(si);
  }
    
  //RMI(Remote Method Invocation) is based on Serialization/Deserialization
  }
  catch (Exception e)
  { e. printStackTrace(); }
    }
}

What is CallableStatement in java?

A procedure exists in database.
JDBC provides CallableStatement to invoke stored procedure available in database.
Below is simple procedure which accepts student id and produces student name as OUT parameter.

DELIMITER //
CREATE PROCEDURE getStdntName1(IN stdntid BIGINT, OUT stdntname VARCHAR(500))
BEGIN
SELECT sname INTO stdntname FROM students WHERE sid=stdntid;
END //
DELIMITER ;

Steps: #1. Save above stored procedure as a abcd.sql in C drive.
#2. From MySQL prompt, run the command “create database aaaa;
#3. Then run “use aaaa;
#4. Then create procedure in db by running “source c:\abcd.sql

Below is Java Program to invoke above stored procedure.

//STEP 1. Import required packages
import java.sql.*;

public class CallableStatementDemo {
   // JDBC driver name and database URL
   static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";  
   static final String DB_URL = "jdbc:mysql://localhost/trial";

   //  Database credentials
   static final String USER = "root";
   static final String PASS = "abcdfe";
   
   public static void main(String[] args) {
   Connection conn = null;
   CallableStatement stmt = null;
   try{
      //STEP 2: Register JDBC driver
      Class.forName(JDBC_DRIVER);

      //STEP 3: Open a connection
      System.out.println("Connecting to database...");
      conn = DriverManager.getConnection(DB_URL,USER,PASS);

      //STEP 4: Execute a query
      System.out.println("Creating statement...");
      String sql = "{call getStdntName1(?, ?)}";//? is place holder for IN and OUT parameters
      stmt = conn.prepareCall(sql);
      
      //Bind IN parameter first, then bind OUT parameter
      int student_id = 9;
      stmt.setInt(1/*parameter number*/, student_id); // This would set ID
      // Because second parameter is OUT so register it
      stmt.registerOutParameter(2, java.sql.Types.VARCHAR);
      
      //Use execute method to run stored procedure.
      System.out.println("Executing stored procedure..." );
      stmt.execute(); //now stored procedure gets executed in the database

      //Retrieve student name with getXXX method
      String student_name = stmt.getString(2);//2 is OUT parameter number
      
      
      System.out.println("Student with ID:" +student_id + " is " + student_name);
      stmt.close();
      conn.close();
   }catch(SQLException se){
      //Handle errors for JDBC
      se.printStackTrace();
   }catch(Exception e){
      //Handle errors for Class.forName
      e.printStackTrace();
   }finally{
      //finally block used to close resources
      try{
         if(stmt!=null)
            stmt.close();
         conn.close();
      }catch(SQLException se2){
      }// nothing we can do
   }//end try
   System.out.println("Done!");
}//end main
}//end JDBCExample

You may also like to read:

How to Connect Java Program to a Database

purpose of join() method in Thread

join() method is defined in Thread class. join() method waits for a thread to die. That means, it causes the currently running threads to stop executing until the thread it joins with completes its task.


class NewThread1 implements Runnable{
	String name; //name of Thread
	Thread t;
	
	NewThread1(String threadname){
		name=threadname;
		t = new Thread(this,name);
		System.out.println("New thread:"+t);
		t.start();
	}
	
	public void run(){
		try
		{
		for(int i=5;i>0;i--)
		{
		System.out.println(name+":"+i);
		Thread.sleep(1000);
		}
		}
		catch(InterruptedException ie){
			System.out.println(name+" Interrupted");
		}
		
		System.out.println(name+" Exiting");
	}
	
	
}


public class JoinCheck {
	public static void main(String args[])
	{
	NewThread1 nt1=new NewThread1("One");
	NewThread1 nt2;
	NewThread1 nt3;
	NewThread1 nt4;
	//start the threads
	//nt1=new NewThread1("One");
	nt2=new NewThread1("Two");
	nt3=new NewThread1("Three");
	nt4=new NewThread1("Four");
	
	threads_status(nt1,nt2,nt3,nt4);
	try
	{
	nt1.t.join();
	nt2.t.join();
	nt3.t.join();
	nt4.t.join();

	
	
	System.out.println("completed all four threads");
	}catch(Exception ien)
	{
		System.out.println("main thread Interrupted");
	}
	
	threads_status(nt1,nt2,nt3,nt4);
	System.out.println("main thread Exiting");
	}

	private static void threads_status(NewThread1 nta,NewThread1 ntb,NewThread1 ntc,NewThread1 ntd)
	{
	System.out.println("Thread One Alive?"+nta.t.isAlive());
	System.out.println("Thread Two Alive?"+ntb.t.isAlive());
	System.out.println("Thread Three Alive?"+ntc.t.isAlive());
	System.out.println("Thread Four Alive?"+ntd.t.isAlive());
	}
	
}

How to Set priority to a Thread

By default all the threads created, get medium priority, unless a specific priority explicitly is set to the thread. Below are the priority related constants provided in Thread class.
Thread.MIN_PRIORITY (value is 0)
Thread.NORM_PRIORITY (value is 5, which is default priority)
Thread.MAX_PRIORITY (value is 10)

Any numeric value between 0 and 10 can be set as priority to a Thread. Below are priority related methods provided in Thread class
void setPriority(int priority);
int getPriority();

A thread with high priority gets allocated with more CPU time, compared to threads with relatively low priority threads. Hence a thread with high priority threads executes faster, compared to low priority threads.

			
class NewThread2 implements Runnable{
	String name; //name of Thread
	Thread t;
	
	NewThread2(String threadname,int priority){
		name=threadname;
		t = new Thread(this,name);
		System.out.println("New thread:"+t);
		t.start();
		t.setPriority(priority);
	}
	
	public void run(){
		try
		{
			for(int i=50;i>0;i--)
			{
			System.out.println(name+":"+i);
			//Thread.sleep(100);
			}
		}catch(Exception ie)
		{
		System.out.println("Exception:");
		ie.printStackTrace();
		}
		System.out.println(name+" Exiting");
	}
}


public class ThreadPriority {
	
	public static void main(String args[])
	{
	//start the threads

	NewThread2 nt2=new NewThread2("Two",Thread.MAX_PRIORITY);
	NewThread2 nt3=new NewThread2("Three",3/*Thread.NORM_PRIORITY*/);
	NewThread2 nt1=new NewThread2("One",Thread.MIN_PRIORITY);
		
	try
	{
	nt1.t.join();
	nt2.t.join();
	nt3.t.join();
	}catch(Exception ien)
	{
	System.out.println("main thread Interrupted");
	}
	
	
	System.out.println("Thread One Alive?"+nt1.t.isAlive());
	System.out.println("Thread Two Alive?"+nt2.t.isAlive());
	System.out.println("Thread Three Alive?"+nt3.t.isAlive());
	
	System.out.println("Main thread has exited");
	
	System.out.println("main thread Exiting");
	}

}

conditional statements in Java

Conditional/Control Flow statements
#1. to perform an action when a condition is true
if(condition)
{
//statements
}
Eg. if(z<20)
{
//statements
}
#2. to perform action1 when a condition is true, and perform another action, when condition is false
if(condition)
{
//statements 1
}else
{
//statements 2
}
#3.
if(condition1)
{
//statements
}
else if(condition2)
{
//statements
}
else if(condition3)
{
//statements
}
else
{
}