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();
	}
}

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");
	}

}

In Thread, purpose of join() and isAlive() methods

As known below are the methods available in Thread class
setName()
getName()
setPriority()
getpriority()
sleep()
start()
join()
isAlive()

When to use join() method. Before we try to understand join(), lets see what is Daemon thread. A Daemon thread is a thread, which keeps on running in the background, even though its parent , has already completed execution, and no more exit. Daemon threads, can be avoided using join() method. Whenever join() is invoked, with a thread object(say t1). Execution of main threads waits, until thread t1 completes execution.

Also isAlive() method is provided, just to check if an invoking thread, is still alive, or has completed execution.
isAlive() returns true if invoking thread is still alive, else returns false.

Below is an example, showing, how main thread is kept alive until all child threads have completed execution.


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());
	}
	
}

Output:
New thread:Thread[One,5,main]
New thread:Thread[Two,5,main]
New thread:Thread[Three,5,main]
Two:5
New thread:Thread[Four,5,main]
Thread One Alive?true
Thread Two Alive?true
Thread Three Alive?true
Thread Four Alive?true
Four:5
One:5
Three:5
Two:4
One:4
Four:4
Three:4
Two:3
Four:3
One:3
Three:3
Two:2
Four:2
One:2
Three:2
Two:1
Four:1
One:1
Three:1
Two Exiting
One Exiting
Four Exiting
Three Exiting
completed all four threads
Thread One Alive?false
Thread Two Alive?false
Thread Three Alive?false
Thread Four Alive?false
main thread Exiting

You may also like to read:
What is Thread pool
How to avoid deadlocks in threads
What is a thread
Start a child thread, from another child thread

How and when to use Thread pool

What is Thread pool

A Thread pool is a set of worker threads created simultaneously, and each thread in this pool gets assigned with a task. Once a thread completes executing the assigned task, the thread goes back and waits in the pool, waiting for next task to be assigned.
Note that the thread does not die, after completion of its task, rather it goes and waits in the pool, for next Task to be assigned with.

Advantages of Thread pool

Limit the maximum number of threads to accomplish a task or set of tasks.
A thread is not started and ended, for every Task. With thread pool, we are avoid, starting and ending of threads multiple times.

Comparison with real life scenario:When ever you may need a paper notebook, you may goto market to purchase one at a time. Other solution would be to get a bunch of them and keep it with you, and use new one when old one is completed.

Situations when Thread pool, can be used

Lets consider a server program, which can process multiple requests simultaneously. A thread pool with a set of worker threads is started, each request is assigned to a thread. After the request is served, and has provided response to client, worker thread goes back and waits in thread pool.With this a worker thread is not started and ended, for each and every request, and hence responding to client requests is faster.

Another example, where we can use thread pools. Consider program to upload huge file. Using a single thread consumes more time, to upload complete file, and this is not recommended solution. Other approach would be to start few threads, each takes care of uploading a part of file. When each thread completes uploading its part, the thread dies. But consider, using thread pool, for this problem. Hence thread pool can provide ideal solution to such problems.

Please check back, for a ThreadPool example

How deadlock occurs in Threads?

In multithreading deadlock situation may occur, when two or more threads compete for two or more resource. Below is simple example, in which threads t1 and t2 compete to lock two objects obj1 and obj2, which end up in deadlock situation.

Thread deadlock
Thread deadlock

After t1 and t2 threads are started, deadlock occurs in following way
1. Thread t1 locks obj1
2. Thread t2 locks obj2
3. Thread t1 tries to lock obj2
4. Thread t2 tries to lock obj1
5. deadlock occurs…and program hangs

class MyThread8 extends Thread{
	Object obj1, obj2;
	
	MyThread8(Object obja, Object objb)
	{
		obj1 = obja;
		obj2 = objb;
	}
	
	public void run(){
        while(true){
            synchronized(obj1){
                synchronized(obj2){
                System.out.println(obj1+"  "+obj2);
                }
            }
        }
    }
}

public class ThreadDeadLockDemo {
     
    public static void main(String a[]){
        String str1 = "first string";
        String str2 = "second string";
        
    	MyThread8 t1 = new MyThread8(str1,str2);
    	
    	MyThread8 t2 = new MyThread8(str2,str1);
    	
    	t1.start();
    	t2.start();
    }
}

How to avoid deadlocks?
It is possible to avoid deadlocks, by taking care of order of locking, while programming. main method in above program can be re written as below, to avoid deadlock.

public class ThreadDeadLockDemo {
     
    public static void main(String a[]){
        String str1 = "first string";
        String str2 = "second string";
        
    	MyThread8 t1 = new MyThread8(str1,str2);
    	
    	MyThread8 t2 = new MyThread8(str1,str2);
    	
    	t1.start();
    	t2.start();
    }
}

Below are steps involved
1.Thread t1 locks str1
2.Thread t2 attempts to lock str1, waits until t1 unlocks str1
3.Thread t1 locks str2
4.Thread t1 unlocks str2
5.Thread t1 unlocks str1
6.Thread t2 acquires lock on str1
….and so on.

Hence deadlock does not occur, in this case.

You may also like to read:
Create Child Thread, from another Child Thread
Advantages of Concurrent Collection over Synchronized Collection
How to create multiple threads

Program to send HTTP Request to Web server

Below is an example on how to send an HTTP request to any web Server like Tomcat, Glass Fish, Web Logic, Web Sphere. Below Java program acts like a simple Web Browser, which sends HTTP GET or POST Request to Web Server, and prints response( from Web Server) to console.

HTTP Protocol is further dependent on TCP/IP Protocol.
i..e HttpURLConnection further uses underlying Sockets to interact with Web Server.

Difference between HttpURLConnection and HttpsURLConnection

Both HttpURLConnection and HttpsURLConnection classes are in java.net package.
HttpURLConnection uses unsecured version of HTTP(Hyper Text Transfer Protocol), where as HttpsURLConnection is secured version of HTTP Protocol.

Both HttpURLConnection and HttpsURLConnection can use any of the HTTP methods, either GET or POST method.

Difference between GET and POST HTTP Methods

HTTP POST
Data is sent thru URL
Eg: /abc.jsp?mytext=fdfsdfsdf&pwd=fgfdgfdgfd
Data is sent internally
Only limited data can be submitted Unlimited data can be submitted to server program
Unsecured compared to POST Secured compared to GET

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.MalformedURLException;

import javax.net.ssl.HttpsURLConnection;

public class HttpURLConnectionEg {

	private final String USER_AGENT = "Test Client";

	public static void main(String[] args) throws Exception {

	HttpURLConnectionEg http = new HttpURLConnectionEg();

	System.out.println("Sending Http GET request to URL:");
	http.sendGet();
	System.out.println("---------------------------------");
	System.out.println("Send Http POST request to URL:");
	http.sendPost();

	}

	// HTTP GET request example
	private void sendGet() throws Exception {

	String url = "http://localhost/index.php";

	URL obj = new URL(url);
	HttpURLConnection con = (HttpURLConnection) obj.openConnection();

	// optional, default Request method is GET
	con.setRequestMethod("GET");

	//add request header
	con.setRequestProperty("User-Agent", USER_AGENT);

	int responseCode = con.getResponseCode();
        //responseCode is numeric value of HTTP response, can be 2XX,3XX,4XX or 5XX

	System.out.println("Sending GET request to URL : " + url);
	System.out.println("Response Code : " + responseCode);

	BufferedReader in = new BufferedReader(
		new InputStreamReader(con.getInputStream()));
	String inputLine;
	StringBuffer response = new StringBuffer();

	while ((inputLine = in.readLine()) != null) {
		response.append(inputLine);
	}
	in.close();

	//print result
	System.out.println(response.toString());

	}

	// HTTP POST request example
	private void sendPost() throws MalformedURLException,IOException{

	String url = "https://localhost/index.php";
	URL obj = new URL(url);
	HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

	//set request method
	con.setRequestMethod("POST");

        //set header values, first parameter is header name, second parameter is header value
	con.setRequestProperty("User-Agent", USER_AGENT);

	String urlParameters = "a=1234&b=5678&c=65465&d=7263543";

	// Send post request
	con.setDoOutput(true);
	DataOutputStream wr = new DataOutputStream(con.getOutputStream());

        //write the bytes of Request Parameters, to the Server
	wr.writeBytes(urlParameters);
	wr.flush();
	wr.close();

	int responseCode = con.getResponseCode();
	System.out.println("Sending POST request to URL : " + url);
	System.out.println("Post parameters : " + urlParameters);

        //responseCode is numeric value of HTTP response, can be 2XX,3XX,4XX or 5XX
	System.out.println("Response Code : " + responseCode);

        //Create BufferedReader, with the input stream of the response from Web Server
	BufferedReader in = new BufferedReader(
		new InputStreamReader(con.getInputStream()));
	String inputLine;
	StringBuffer response = new StringBuffer();

	while ((inputLine = in.readLine()) != null) {
		response.append(inputLine);
	}
	in.close();

	//Now the response from Web Server, is in response StringBuffer
        //Then print response on the console
	System.out.println(response.toString());

	}

}

You may also like to read:
What is a network port?

Create Thread using Anonymous inner class

As briefed, a Thread is light weight process.

Below is an example, on how to create and start Thread, using Anonymous inner class.

Create Anonymous inner class, which extends from java.lang.Thread and override public void run() method.

public class ThreadAnonymousInnerClass {
	public static void main(String args[])
	{
		Thread t1=new Thread(){
		public void run(){
		for(int i=0;i<=10;i++){
		try{
		System.out.println("Thread t1: "+i);
		Thread.sleep(100);  //100 milliseconds
		}catch(InterruptedException e){
		System.out.println("Exception:"+e.getMessage());
		}
		}
		}
		};

		t1.start();

		for(int i=0;i<=10;i++){
		try{
		System.out.println("Main Thread: "+i);
		Thread.sleep(100);  //100 milliseconds
		}catch(InterruptedException e){
		System.out.println("Exception:"+e.getMessage());
		}
		}
	}
}

Create Anonymous class by implementing Runnable interface

How to create Thread, using anonymous class for Runnable. In below example, we are creating object of an anonymous class which implements Runnable interface.

public class ThreadAnonymousRunnable {
	public static void main(String args[])
	{
		new Thread( new Runnable() {
		    public void run() {

              for(int i=0;i<10;i++)
    	      {
    		System.out.println("child_thread: "+i);
    		try
    		{
    			Thread.sleep(100);
    		}catch(InterruptedException ie){
    			System.out.println(ie.getMessage());
    		}
    	     }
		    }
		}).start();

		for(int i=0;i<10;i++)
    	        {
    		System.out.println("main_thread: "+i);
    		try
    		{
    			Thread.sleep(100);
    		}catch(InterruptedException ie){
    			System.out.println(ie.getMessage());
    		}
    	        }
	}
}

Further reducing size of code

public class ThreadAnonymousRunnable {

	private static void thread_body(String thread_name)
	{
		for(int i=0;i<10;i++)
    	{
    		System.out.println(thread_name+": "+i);
    		try
    		{
    			Thread.sleep(100);
    		}catch(InterruptedException ie){
    			System.out.println(ie.getMessage());
    		}
    	}
	}

	public static void main(String args[])
	{
		new Thread( new Runnable() {
		    public void run() {

		    	thread_body("child_thread");
		    }
		}).start();

		thread_body("main_thread");
	}
}

You may also like to read:
purpose of synchronized keyword
how to use synchronized with a class
how to use synchronized with a method
what are concurrent collections