multithreading in java

MultiThreading:

Q. What is Multithreading ? why it is required ?

Ans: Multithreading is a technique that allows a program or a process to 
        execute many tasks concurrently(at the same time and parallel).
For Example:
I have a requirement to develop one application for following tasks ----
Download one file of size 1GB(time required 10mns)
Read the Student info from file and display to console.
Read the Employee info from DB and store to another file.
public static void main(String args [])
{
downloadFile();
readStudentInfo();
        readEmployInfo();
}
By default it will be executed sequentially, so it will take more time to execute.
If you are using any application that will be used by multiple users at the same time then you may get the requirement to execute the same or different statement concurrently. This  type of requirement can be implemented using multithreading concept.

Thread :

Q. What is a thread ?

A thread is a light-weight subprocess,a smallest unit of processing.
It has a separate path of execution.
It shares the memory area of process.




The thread’s execution will be managed by the operating system and the processor is a resource managed by OS.
If you are developing java application then you will perform the task using the java object, java object is not known for the operating system, so to achieve multithreading concept you need to use some low- level implementation.
Instead of you will define low-level implementation java provides built-in support for multithreaded programming. A multithreaded program contains two or more parts that will run concurrently. Each part of the program is called a thread, and each thread has a separate execution. 

Classes  and Interfaces used for multithreading:
 
Following classes and the interfaces can be used to handle multithreading concept.
Classes:
Java.lang.Thread
Java.lang.ThreadGroup
Java.util.concurrent.Executor (from java 5)
Java.util.concurrent.ThreadPoolExecutor (from java 5)
etc ..
Interfaces:
Java.lang.Runnable
Java.util.concurrent.Executor (from java 5)
Java.util.concurrent.ExecutorService (from java 5)
etc..
In java.lang.Thread class java vendor has provided some methods to get the information about the thread or to perform some task by using the threads.
To get the current thread:
public static native Thread currentThread();
To get the ThreadGroup for the thread:
public final ThreadGroup getThreadGroup();

Q. what will happen if u try to execute the following statement ?
package com.jlcindia.thread;
import java.util.concurrent.Executor;
public class ThTest1
{
public static void main(String args[])
{
System.out.println("main started");
System.out.println("length: "+args.length);
for(int i=0;i<args.length;i++)
{
System.out.println("Args: "+i+"\t"+args[i]);
}
Thread th=Thread.currentThread();
ThreadGroup tg=th.getThreadGroup();
new Student();
System.gc();
for(int i=0;i<10;i++)
{
System.out.println(i+"\t"+th.getName()+"\t"+tg.getName);
}
System.out.println("main completed");
}
}
class Student
{
public void finalize()
{
System.out.println("in finalize of student class");
Thread th=Thread.currentThread();
ThreadGroup tg=th.getThreadGroup();
for(int i=20;i<40;i++)
{
      System.out.println(i+"\t"+th.getName()+"\t"+tg.getname);
}
}
}
Answer:When u are using java.exe by specifying the class name then it request  
              some memory space from the OS.
If the memory will not be allocated then the JVM will not be started    
   successfully and the error message will be displayed.
If the requested memory will be allocated then JVM will be started.
When the JVM will be started It will create some thread group to collect the various thread into the group.
Some Thread group will be ----
main
system
etc..
Some thread object will be created by the JVM and will be added in the corresponding threadGroup.
Some threads will be ----
main: in main threadGroup
finalizer: in system threadGroup


By using main thread the remaining statement(task) will be performed.
1. Main thread will verify the specified class file available or not, if not found
    then the corresponding error will be displayed.
2. If the class file will be available then it will verify the class file, if the class file
    is invalid then the corresponding error will be displayed.
3. If the class file is valid then :

       a. Upto java 6 the class will be loaded, initialized (static block will be
           executed) and the main method will be verified.
         • If not available then error message will be displayed.
         • If available then will be invoked.
       b.  From java 7 the JVM will verify the class file with main method.
         • If not available then the class will not be loaded and error message will
            be displayed.  
         • If available then the class will be loaded, initialized and main  method
            will be invoked.

4. To execute the main method thread will perform the following tasks.
The  number of argument specified as CLA will be collected.
String array object will be created with the size as the number of values
    specified as CLA.
All the values will be stored in the corresponding index in the String array.
Main thread will invoke the main method with the class name by providing
    String array object as argument.
After completing the main method the main thread will be destroyed.

Q. Can you execute java application without using main() method ?
Ans:   
Yes, (using static block) before java 7
No, from java 7.

Defining custom thread:
If you want to define custom thread to execute the statement concurrently then you need to provide the API provided by the java vendor. If you are defining the custom thread then it must be the subtype of java.lang.Runnable interface either directly or indirectly.
Java.lang.Thread is also implementing java.lang.Runnable interface. 
Basically you have two options to define the custom thread:
By extending java.lang.Thread class
By implementing java.lang.Runnable interface.

Implementing the Custom thread by extending Thread class:
1. Define a class by extending java.lang.Thread.
2. Override the following method where you can define the implementation that will be executed concurrently.
public void run()
3. To start the thread you need to use the start() method from the thread class.
Note:
Upto java 2 start() is native.
From java 5 start() is not native but internally native implementation will be  
   used.
4. If you are invoking run() explicitly then it will be executed as normal method 
   (not as multithreaded environment).
5. You cannot start one thread more than once. If you try to start then following
   exception will be thrown
Java.lang.IllegalThreadStateException

Example1:
package com.manish.thread;
public class CThTest2 
{
public static void main(String[] args) 
{
Thread th1=new AThread();
Thread th2=new BThread();
th1.start();
th2.start();
Thread th=Thread.currentThread();
for(char ch='A';ch<='Z';ch++)
{
System.out.println(th.getName()+"\t character is: "+ch);
}
}
}
class AThread extends Thread
{
public void run()
{
new Service().downloadFile();
}
}
class BThread extends Thread
{
public void run()
{
new Service().showStudentInfo();
}
}
class Service
{
void downloadFile()
{
Thread th=Thread.currentThread();
for(int i=0;i<=100;i+=5)
{
System.out.println(th.getName()+"\t Downloaded "+i+"%");
}
}
void showStudentInfo()
{
Thread th=Thread.currentThread();
for(int i=101;i<=125;i++)
{
System.out.println(th.getName()+"\tStudent info with id: "+i);
}
}
}
Example2:
package com.manish.thread;
public class CthTest2a 
{
public static void main(String[] args) 
{
Athread th1=new Athread("manish","sri");
Athread th2=new Athread("sharma","123");
th1.start();
th2.start();
}
}
class Athread extends Thread
{
String unm;
String pwd;
public Athread(String unm,String pwd)
{
this.unm=unm;
this.pwd=pwd;
}
public void run()
{
new Service().verifyUser(unm, pwd);
}
}

class Service
{
void verifyUser(String unm,String pwd)
{
Thread th=Thread.currentThread();
for(int i=0;i<=10;i++)
{
System.out.println(th.getName()+"\tverifying "+unm+"\t"+pwd);
}
}
}


Implementing the Custom thread by implementing Runnable  Interface :
1. Define a class by implementing java.lang.Runnable interface. 
2. Override the following method in the class
                  public void run()
3. Since your class is not the subclass of java.lang.Thread class, so you cannot  
    invoke start method directly.
4. You need to create the java.lang.Thread class object by using the  constructor 
    with the java.lang.Runnable type as parameter. You need to specify the  
    subclass object of Runnable as argument. 
5. With the object of thread class you can invoke the start() method.
In this condition the run method available in the specified object(subclass of java.lang.Runnable) will be executed.
Method 1:

package com.manish.thread;
public class CThTest2 
{
public static void main(String[] args) 
{
AThread ath=new AThread();
BThread bth=new BThread();
Thread th1=new Thread(ath);
Thread th2=new Thread(bth);
th1.start();
th2.start();
}
}
class AThread implements Runnable
{
public void run()
{
new Service().downloadFile();
}
}
class BThread implements Runnable
{
public void run()
{
new Service().showStudentInfo();
}
}
class Service
{
void downloadFile()
{
Thread th=Thread.currentThread();
for(int i=0;i<=100;i+=5)
{
System.out.println(th.getName()+"\t Downloaded "+i+" %");
}
}
void showStudentInfo()
{
Thread th=Thread.currentThread();
for(int i=101;i<=125;i++)
{
System.out.println(th.getName()+"\tStudent info with id: "+i);
}
}
}


Method 2:
package com.manish.thread;
public class CThTest3 
{
public static void main(String[] args) 
{
Runnable r1=new Runnable(){
public void run()
{
  Thread th=Thread.currentThread();
  for(int i=0;i<10;i++)
        {
   System.out.println("Annonymous: "+i+"\t"+th.getName());
   }
}
};

Thread th1=new Thread(r1);
Thread th2=new Thread(r1);
th1.start();
th2.start();
}
}

Method 3:
package com.manish.thread;
public class CThTest4 
{
public static void main(String[] args) 
{
System.out.println(Thread.currentThread().getName());
Mthread mth1=new Mthread();
Mthread mth2=new Mthread();
mth1.start(); //mth1.th.start();
mth2.start(); //mth2.th.start();
}
}
class Mthread implements Runnable
{
Thread th=null;
Mthread()
{
th=new Thread(this);
}
public void run()
{
Thread th=Thread.currentThread();
for(int  i=0;i<10;i++)
{
System.out.println("Mthread: "+i+"\t"+th.getName());
}
}
public void start()
{
th.start();
}
}

Method 4:
package com.manish.thread;
public class CThTest5 
{
public static void main(String[] args) 
{
System.out.println(Thread.currentThread().getName());
new Nthread();
new Nthread();
}
}
class Nthread implements Runnable
{
Thread th=null;
Nthread()
{
th=new Thread(this);
th.start();
}
public void run()
{
Thread th=Thread.currentThread();
for(int  i=0;i<10;i++)
{
System.out.println("Nthread: "+i+"\t"+th.getName());
}
}
}
Note: 
When you are executing multiple threads then for each thread separate stack will be created. If any problem occurred in one thread execution then it won’t terminate the execution of other thread.
Example:
package com.manish.thread;
public class CThTest6 
{
public static void main(String[] args) 
{
ThTest th=new ThTest();
th.start();
Thread th1=Thread.currentThread();
for(char ch='A';ch<='Z';ch++)
{
if(ch=='N')
{
int x=10/0;
}
System.out.println("char: "+ch+"\t"+th1.getName());
}
}
}
class ThTest extends Thread
{
public void run()
{
Hello h=new Hello();
h.show();
}
}
class Hello
{
void show()
{
Thread th=Thread.currentThread();
for(int i=0;i<10;i++)
{
System.out.println("show: "+i+"\t"+th.getName());
}
}
}

Output:
char: A main
char: B main
char: C main
char: D main
char: E main
char: F main
char: G main
char: H main
char: I main
char: J main
char: K main
char: L main
char: M main
show: 0 Thread-0
show: 1 Thread-0
show: 2 Thread-0
show: 3 Thread-0
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.jlcindia.thr.CThTest6.main(CThTest6.java:13)
show: 4 Thread-0
show: 5 Thread-0
show: 6 Thread-0
show: 7 Thread-0
show: 8 Thread-0
show: 9 Thread-0




Q. What is the best option and recommendable to define the custom thread ?
Ans: By implementing java.lang.Runnable interface.
Because if you are implementing any interface then you have a  chance to extend any other class. If you are extending java.lang.Thread class then you can’t extend other class. 
Q. Can you overload the run method in your class?
Ans: Yes
Q. Can the overloaded run method be invoked by the JVM when the thread will be started?
Ans: No
Q. Can you define the run method as abstract or static?
Ans: No
Q. Can you define the run() method as synchronized ?
Ans: Yes, but not recommendable because only one thread will invoke the run method at a time (it will stop the concurrency).     
Q. Can you write the thread class without overriding the run method in the class ?
Ans: Yes, but run() should be inherited from the super class.
When you are defining the custom thread then compiler will verify the run method implementation available or not. It may be overridden or inherited from the super class. you can define thread class without overriding the run() method if it is inherited from the superclass.
Example:
package com.manish.thread;
public class CTHTest7 
{
public static void main(String[] args) 
{
HelloThread hth=new HelloThread();
Thread th=new Thread(hth);
th.start();
}
}
class Helo extends Thread
{
void downloadFIle()
{
Thread th=Thread.currentThread();
for(int i=0;i<10;i++)
{
System.out.println(i+"\t"+th.getName());
}
}
public void run()
{
downloadFIle();
}
}
class HelloThread extends Helo implements Runnable
{
}



After creating the thread when you are invoking the start()  method then the thread will be started and will be available in the Runnable/Ready to run state. The thread available in the Runable state will be selected by the OS depending on the scheduler and the CPU time will be allocated.After completing the allocated  time the thread will be moved to Runnable state and so on.
Note:  If the Thread is in the Running state it is using CPU to perform the tasks.
Yield():
You can use Yield() method with the thread to transfer the thread to Runnable state and the other thread from Runnable that has higher priority will get the CPU time.
Sleep():
If you are  invoking the sleep() method then the thread will be transferred to  
    sleep state.
After completing the specified time the thread will be moved to Runnable  
   state.
If the thread is in sleep state and if it is locking any resource then the lock on  
   the resource will not be released.
Wait():
If any object is used to invoke wait() method then the thread will be moved to  
    wait state.
If the thread will be moved to wait state then the locked resource will be  
    released. 
If you are invoking the wait() method by specifying some time then after  
    completing the time it will be moved to Runnable state.
If you want you can move the thread to Runnable state before completing the  
    time by invoking notify()/ notifyAll() method with the same object that was  
    used to invoke the wait() method.  
If you are invoking the wait() method without parameter then you need to  
    invoke notify/notifyAll() to move the thread to Runnable state.
Note: wait() must be called from synchronized context and with the locked object.          
Blocked state:
      If the thread has requested for any resource that is not available or currently used by another thread then the current thread will be moved to the blocked state.When the requested resource will be available then the thread will be moved to Runnable state.
Destroy state:
Once the thread will be completed then it will be destroyed, or you can invoke stop() to destroy the thread explicitly.  
Deadlock:
If you have some requirement where two thread has to be executed and can use two resources then:

Case 1:
            If there is no locking can be executed successfully.

Case 2:
If the threads are locking the corresponding resources and to complete first thread second resource is required but for the second  thread first resource is not required then when the second thread is completed then the second resource can be used by the first thread and first thread will be completed.



Case 3:
If the thread is locking the corresponding resources and to complete the first thread second resource is required and to complete the second thread first resource is required. In this condition both the resource will not be released and both the thread will be moved to the blocked state. This condition is called deadlock condition.



Synchrinization: 
It is a process of locking the object. If the object will be locked by one thread then the thread will be owner for that object. The same object cannot be used to access any synchronized content concurrently by the other thread.
The non-synchronized content can be accessed with the locked object by other thread. By using the synchronization you can stop or restrict the concurrency.
Types of synchrinization:
1. Method level Synchrinization
2. Block level Synchrinization


1. Method level Synchronization:
In the case of method level synchronization you need to define method with  
   the synchronization keyword. In this condition the object that will be used to  
   invoke the method will be locked by the thread.
Syntax:
[modifier] synchronized <return type><method name>(<params>)
{
//statement
                  }
In the method level synchronization after completing the execution of the method of the object lock will be released.
2. Block level Synchronization:
In the case of block level synchronization you need to define the block with   
   synchronized keyword. You need to specify one object as the argument to the  
   block that will be locked.
In this condition you can lock other than the current object and you can lock  
   the object for some statement of the method (not for complete method). 
After completing the execution of the synchronized block the lock will be  
   released.
Object locking:
When the object will be created by the JVM then for each object some lock will 
   be available. By default the lock will be disabled.
Whenever the object will be used to invoke some synchronized method or if  
   the object will be used as the argument to the synchronized block then the  
   lock will be enabled and will be handed over to the current thread.
If the method is instance method then the object you are using to invoke the 
   method will be locked.
If the method is static method then the default object of your class (i.e  
   java.lang.Class  type object will be locked).
   If the object is locked by one thread then the same object cannot be used to  
   access any synchronized content, but can be used to access non-synchronized context.
When the thread is using some object to invoke any method then the following task will be performed…………..
1. Method will be verified whether it is synchronized or not.
2. If it is not synchronized then the object will be used to invoke the method.
3. If the method is synchronized then JVM will verify the lock on the object.
4. If the object is not locked by the other thread then the method will be invoked.
5. If the object is locked by the other thread then the method will not be invoked with the object until the lock will be released.



Various scenerios for synchronization:
If you have an account class with the following three methods
1. Transfer
2. Withdraw
3. updateInfo()
we have defined some thread class to invoke this methods concurrently.If one thread is using ac1 object to invoke transfer() method and other thread is using some object to invoke some methods then in the following condition what are the threads will be executed concurrently with the first thread.









Q. Why wait() method must be called from synchronized context ?
Ans: if you are calling wait() with some object then it will try to release the lock on the corresponding object. if the lock is not enabled then it will not be able to release the lock and the following exception will be thrown----
Java.lang.IllegalMonitorStateException 

Case1:
class Hello
{
ArrayList al=new ArrayList();
void show()
{
wait();       //current object will be used not locked
}
}

Case2:
class Hello
{
ArrayList al=new ArrayList();
synchronized void show()
{
wait();       //current object will be used it is locked
}
}
Case3:
class Hello
{
ArrayList al=new ArrayList();
synchronized void show()
{
al.wait();       //ArrayList object will be used it is not locked
}
}
Case 4:
class Hello
{
ArrayList al=new ArrayList();
void show()
{
synchronized(this)
{
wait();

}       //current object will be used it is locked
}
}
Case 5:
class Hello
{
ArrayList al=new ArrayList();
void show()
{
synchronized(this)
{
al.wait();
}       //ArrayList object will be used it is not locked
}
}
Case6:
class Hello
{
ArrayList al=new ArrayList();
void show()
{
synchronized(al)
{
al.wait();
}       //ArrayList object will be used it is locked
}
}
Case 7:
class Hello
{
ArrayList al=new ArrayList();
void show()
{
synchronized(al)
{
wait();
}       //current object will be used it is not locked
}
}
So when you are invoking wait () method with some object then the lock on the object must be enabled and to enable the lock you must have to use synchronized context.
Q. Can you acquire lock on class/java.lang.class object or not?
Ans: yes
Q. How can Class object be locked using method level synchronization?
Ans: Define static synchronized method.
Q. How can class object be locked using block level synchronization?
Ans:
Synchronized(Hello class)
{
//statements
}
Class cl=h1.getClass();
Synchronized (cl) {}
Q. Why wait()/notify()/notifyAll() is defined in the object class?
Ans: 
wait () will be used to release the lock on the object. It is not mandatory that only the thread object can be locked. If any other object is locked and you want to release that then you want to use wait().To give the guarantee that the wait() can be invoked with any object to release the lock, it is defined in the object class. 
If the thread is in wait state then you cannot use that thread to invoke any method for notifying that…….


Constructors from java.lang.Thread class : 
Public Thread(ThreadGroup,Runnable);
Public Thread (Runnable)
Public Thread (String)
Public Thread (Runnable,String)
Public Thread (ThreadGroup,String)
Public Thread (ThreadGroup,Runnable,String name)
Thread Name:
When you are creating the Thread object then for each thread some name will be available. if you are not providing then by default JVM will provide as follows:
Thread < int value >
<  int value > will start from 0 and will be increased by 1.
While creating the Thread object if you want to specify the user defined name then you can use the constructor of the Thread class that have String as parameter.
To specify the name after creating the object you can use the following 
    method with Thread class object.
public final void setName(String name)
To get the name of the thread you can use the following method
public final String getName()

ThreadGroup:
It is a class that indicates the group information of the thread. Whenever you 
   are creating the thread the thread will be added into some group.
To get the ThreadGroup object you need to invoke the following method with 
   the Thread object.
public final ThreadGroup  getThreadGroup()
If you want to specify the thread in the custom ThreadGroup then you can use 
   the constructor of the Thread class with ThreadGroup as parameter.
If you are not specifying  ThreadGroup then by default thread will be added 
   to in the ThreadGroup of the creator thread (the thread that is creating the 
   current thread).




Priority thread: 
By default for every thread some integer value will be available that specifies the priority of the thread. To specify or to access the priority you can use the following method with the thread object.
1. Public final void setPriority(int pr)
2. Public final int getPriority()
The range of the priority will be from 1 to 10. If you are specifying other than this range then you will get the following exception
Java.lang.IllegalArgumentException
1 will be minimum priority
5 will be normal priority
10 will be the maximum priority
For these values the following constant defined in the thread class:
    public static final int MIN_PRIORITY=1
public static final int NORM_PRIORITY=5
public static final int MAX_PRIORITY=10
The priority will be used to execute the thread if operating system is using priority based scheduler. The thread with the higher priority will be executed first.
Note: By default thread priority will same as creator thread.
Daemon Thread:
It is also known as service thread that will be used to provide service to other 
   thread.
If the thread is normal thread then it will be executed completely.
If the thread is daemon thread then there is no guarantee that it will be 
   executed completely.
When the main thread will be destroyed then the daemon thread will be
   destroyed automatically.
To verify that the thread is daemon or not you can use the following method:
public final boolean isDaemon()
to specify the thread as Daemon you need to use the following methodpublic  
   final boolean setDaemon(Boolean daemon)
Garbage Collector is an example of the daemon thread.
Note:After starting the thread the thread cannot be changed to Daemon thread.
Join method:
This method will be used to join one thread at the end of another thread.
In main thread:
th1.join();    ---->  Main thread will be joined at the end of th1.
In th2 thread:
th3.join()     -----> th2 will be joined at the end of th3 thread.

1 comment:

  1. Java/J2Ee Tutorials: Multithreading In Java >>>>> Download Now

    >>>>> Download Full

    Java/J2Ee Tutorials: Multithreading In Java >>>>> Download LINK

    >>>>> Download Now

    Java/J2Ee Tutorials: Multithreading In Java >>>>> Download Full

    >>>>> Download LINK jT

    ReplyDelete