Translate

Wednesday, November 7, 2012

THREADS AND CONCURRENCY


THREADS AND CONCURRENCY

Introduction

Multitasking Executing several tasks simultaneously is called Multitasking’, There are 2 types of multitasking.

1) Process based Multitasking.
2) Thread based Multitasking.

Process based Multi Tasking

Executing several tasks simultaneously where each task is a separate independent process is called ‘Process based Multitasking’.

Ex:While writing java program in the editor we can run MP3 player. At the same time we can download a file from the net. All these tasks are executing simultaneously and independent of each other. Hence it is process based Multitasking. Process based Multitasking is best suitable at O.S level.

Process based Multi Tasking

Executing several tasks simultaneously where each task is a separate independent part of the same program is called Thread based Multitasking. This type of multitasking is best suitable
at programmatic level. Java provides in built support for thread based multitasking by providing rich library (Thread, ThreadGroup, Runnable ..etc) Whether it is Processbased or Threadbased the main objective of multitasking is to reduce response time and improve performance of the system. The main application area of multithreading is videogames implementation, ,Multimedia graphics
…etc.

Defining Instantiating, Starting the Thread

We can define instantiate and starting a thread by using the following 2- ways.

1) By extending Thread Class.
2) By implementing Runnable interface.

By extending Thread Class

Ex:
class MyThread extends Thread
{
public void run()
{
for (int i=0; i<10 i="i" o:p="o:p">
{
System.out.println("Child Thread");
}
}
}
class MultiThreadDemo
{
public static void main(String[] args) throws  InterruptedException
{
MyThread t = new MyThread();
t.start();
for(int i = 0; i<10 i="i" o:p="o:p">
{
System.out.println("Main Thread");
}
}
}
Case1 :Thread Shedular:
If multiple threads are there then which thread will get chance first for execution will be decided by “Thread Scheduler”. Thread Scheduler is the post of JVM. The behavior of thread scheduler is vendor dependent and hence we can’t expect exact O/P for the above program.
The possible Outputs are:
 (1) Child   (2) Main (3) Main
        .                    .         Child
        .                    .         Main
        .                    .         Child…………..

Case2:
The difference between t.start() & t.run(): In the case of t.start() a new thread will be created and which is responsible for the execution
of run. But in the case of t.run() no new thread will be created and run() method will be executed just like a normal method by the main thread. Hence in the above program if we are replacing t.start() with t.run() then the O/P is
Child
Child
Child
Child
Main
Main
  .
  .
  .
  .
           
Case3:
Importance of Thread Class start() method: After Creating thread object compulsory we should perform registration with the thread
Main scheduler. This will take care by start() of Thread class, So that the programmers has to concentrate on only job. With out executing Thread class start() method there is no chance of start a new Thread in java.
start()
{
Register our thread with the thread scheduler. Invoke run method.
}
Case4:
If we are not overriding run() method:Then the thread class run method will be executed which has empty implementation.

Ex:
class MyThread extends Thread
{
}

class ThreadDemo
{
public static void main(String arg[])
{
MyThread t = new MyThread();
t.start();
}
}
O/P:- no output
Case5:
If we are overriding start() method:
Ex:
class MyThread extends Thread
{
public void start()
{
System.out.println("start() method");
}
public void run()
{
System.out.println("run method");
}
}
class ThreadDemo
{
public static void main(String arg[])
{
MyThread t = new MyThread();
t.start();
}
}
O/P:- start() method In this case start() method will be executed just like a normal method.

Case6:
class MyThread extends Thread
{
public void start()
{
super.start();
System.out.println("start() method");
}
public void run()
{
System.out.println("run method");
}
}
class ThreadDemo
{
public static void main(String arg[])
{
MyThread t = new MyThread();
t.start();
System.out.println("main method");
}
}
O/P:- start() method.
run method.
main method.

Life cycle of Thread
When u write new MyThread()




Note:- we can’t stop a running Thread explicitly. But until 1.2 version we can achieve this by using stop() method but it is deprecated method. Similarly suspend() and resume() methods also deprecated.
After starting a thread we are not allowed to restart the same thread once again, violation leads to Runtime Error saying “IllegalThreadStateException”.

MyThread t = new MyThread();
t.start();
t.start();  àIllegal Thread state Exception.

By Implementing Runnable Interface
We can define a Thread by implementing runnable interface also. Runnable interface available in java.lang package and contains only one method
public void run();
Ex:
class MyRunnable implements Runnable
{
public void run()
{
for(int i = 0;i<=10;i++)
{
System.out.println("Child Thread");
}
}
}
class ThreadDemo
{
public static void main(String arg[])
{
MyRunnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
for(int i = 0;i<=10;i++)
{
System.out.println("Main Thread");
}
}
}
Possible O/P:
          Main Thread
          Child Thread
          Main Thread
          Child Thread
Main Thread
          Child Thread
          Main Thread
          Child Thread



Ex:
MyRunnable r = new MyRunnable();
Thread t1 = new Thread();
Thread t2 = new Thread(r);

Case1:
t1.start();
A new thread will be started and executes thread class run method(Which is having empty
implementation).
Case2:
t1.run();
No new thread will be created and thread class run() method will be executed just like a normal method call.
Case3:
t2.start();
A new thread will be created and responsible for execution of MyRunnable run method.
Case4:
t2.run();
No new thread will be created and MyRunnable run method will be executed just like a normal method call.
Case5:
r.run();
No new thread will be created and MyRunnable run method will be executed just like a normal method call.
Case6:
r.start();
Compiler Error: MyRunnable doesn’t contain start method.
In which of the following cases a new thread will be started.
1) t1.start(); |/
2) t1.start(); |/
3) r.start();
4) t1.run();
5) t2.run();
6) r.run();
Note:- Among 2- approaches of defining a thread – implements Runnable is always recommended to use in the 1st approach as we are already extending thread class. There is no chance of extending any other class. Hence we are missing the key benefits of oops inheritance(reusability) . hence this approach is not recommended to use.
Hybrid Mechanism To define a thread(not recommended to use)

Ex:
class MyThread extends Thread
{
public void run()
        {
 System.out.println("Child Thread");
          }
}
class HybridThreadDemo
{
public static void main(String arg[])
{
MyThread t1 = new MyThread();
Thread t = new Thread(t1);
t.start();
System.out.println("Main Thread");
}
}
O/P:- Child Thread
Main Thread
Or
Main Thread
Child Thread
Thread class construtors
1) Thread t = new Thread();
2) Thread t = new Thread(Runnable r);
3) Thread t = new Thread(String name);
4) Thread t = new Thread(Runnable r, String name);
5) Thread t = new Thread(ThreadGroup g, String name);
6) Thread t = new Thread(ThreadGroup g, Runnable r);
7) Thread t = new Thread(ThreadGroup g, Runnable r, String name);
8) Thread t = new Thread(ThreadGroup g, Runnable r, String name, long stacksize);



setting and getting the name of a Thread
Thread class defines the following methods to set and get the name of a Thread.
1) public final void setName(String name);
2) public final String getName();

Ex:
class Test
{
public static void main(String arg[])
{
System.out.println(Thread.currentThread().getName());
Thread.currentThread().setName("New Thread");
System.out.println(Thread.currentThread().getName());
}
}
O/P:-main
          New Thread

Thread Priorities

Every Thread in java having some priority. The range of valid thread priorities is (1-10) (1 is least & 10 is Highest). Thread class defines the following constant for representing some standard priorities.
Thread.MIN_PRIORITY 1
Thread.NORM_PRIORITY 2
Thread.MAX_PRIORITY 3
Thread scheduler use these priorities while allocating C.P.U. The Thread which is having highest priority will get chance first for execution. If two threads having the same priority then which thread will get chance first for execution is decided by Thread Scheduler, which is vendor dependent i.e we can’t expect exactly. The default priority for the main thread only the 5, but for all the remaining threads the priority will be inherit from parent i.e what ever the parent has the same priority the child thread also will get. Thread class contains the following methods to set and get priorities of thread.
1)    public final void setPriority(int priority) where priority should be from 1-10 other wise R.E: IllegalArgumentException. 2) public final int getPriority();

Ex:
class MyThread extends Thread
{
public void run()
{
for (int i=0; i< 10 ; i++ )
{
System.out.println("Child Thread");
}
}
}
class ThreadPriorityDemo
{
public static void main(String arg[])
{
MyThread t = new MyThread();
System.out.println(t.getPriority());
t.setPriority(10);
t.start();
for(int i =0;i<10 i="i" o:p="o:p">
{
System.out.println("Main Thread");
}
}
}
O/P:-Main Thread
          Child Thread
          Main Thread
          Child Thread
Main Thread
          Child Thread
          Main Thread
          Child Thread

Some Operating Systems may not provide support for thread priorities.

Preventing Thread from execution

We can prevent a thread from execution by using the following methods.
1) yield()
2) join()
3) sleep()

yield()

The thread which is called yield() method temporarily pause the execution to give the chance for remaining threads of same priority. If there is no waiting thread or all waiting threads having low priority. Then the same thread will get the chance immediately for the execution. public static native void yield();





Ex:
class MyThread extends Thread
{
public void run()
{
for (int i=0; i< 10 ; i++ )
{
System.out.println("Child Thread");
Thread.yield();
}
}
}
class YieldDemo
{
public static void main(String arg[])
{
MyThread t = new MyThread();
t.start();
for(int i =0;i<10 i="i" o:p="o:p">
{
System.out.println("Main Thread");
}
}
}

In this case main thread will get chance more no of times for execution. Because child thread intentionally calling “yield()” method. As the yield method is native method some Operating system may not provide the support for this.

join()
If a thread wants to wait until some other thread completion then we should go for join method.

Ex:If a thread t1 executes t2.join(), then t1 will be entered into waiting state until t2 completion.

public final void join() throws InterruptedException
public final void join(long ms) throws InterruptedException
public final void join(long ms, int ns) throws InterruptedException









Ex:
class MyThread extends Thread
{
public void run()
{
for (int i=0; i< 10 ; i++ )
{
System.out.println("Child Thread");
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
}
}
}
}
class JoinDemo
{
public static void main(String arg[])throws InterruptedException
{
MyThread t = new MyThread();
t.start();
t.join(); à 1
//t.join(4000)
for(int i =0;i<10 i="i" o:p="o:p">
{
System.out.println("Main Thread");
}
}
}
O/P:-
                   Child Thread                                  Child Thread
Child Thread                                  Child Thread
Child Thread                                  Child Thread
Child Thread                                  Main Thread
Child Thread                                  Main Thread
t.join()à    Child Thread         t.join(4000)à  Main Thread
                   Main Thread                                  Main Thread
                   Main Thread                                  Child Thread
                   Main Thread                                  Main Thread
                   Main Thread                                  Main Thread
                   Main Thread                                  Main Thread
Main Thread                                  Child Thread
Main Thread                                  Child Thread
Main Thread                                  Child Thread
Main Thread                                  Child Thread





sleep()
If a method has to wait some predefined amount of time with out execution then we should go for sleep() method.

public static void sleep(long ms)throws InterruptedException
public static void sleep(long m, int m)throws InterruptedException





Ex:
class MyThread extends Thread
{
public void run()
{
try
{
for (int i = 0;i<10 i="i" o:p="o:p">
{
System.out.println("This is Lazy Method");
Thread.sleep(1000);
}
}
catch (InterruptedException e)
{
System.out.println(e);
}
}
}
class SleepDemo
{
public static void main(String arg[])throws InterruptedException
{
MyThread t = new MyThread();
t.start();
System.out.println("Main Thread");
}
}

O/P:- Main Thread
This is Lazy Method
This is Lazy Method
This is Lazy Method
This is Lazy Method
This is Lazy Method

interrupting a thread
we can interrupt a sleeping or waiting thread by using interrupt method of thread class.
public void interrupt()

when ever we are calling interrupt() the target thread may not be effected immediately. At the time of calling interrupt if the target thread is not in sleeping or in waiting state interrupt call will wait
until target thread entered into sleeping or waiting state.

Ex:
class MyThread extends Thread
{
public void run()
{
try
{
for (int i = 0;i<10 i="i" o:p="o:p">
{
System.out.println("This is Lazy Method");
// Thread.sleep(3000); 1
}
Thread.sleep(3000); 2
}
catch (InterruptedException e)
{
System.out.println(e);
}
}
}



class InterruptDemo
{
public static void main(String arg[])throws InterruptedException
{
MyThread t = new MyThread();
t.start();
t.interrupt();
System.out.println("Main Thread");
}
}
O/P:-
Sleep() used inside for loop à This is Lazy Method
                                                        Main Mehod
                                                                             Java.lang.InteruptedException:sleep interrupted


                                                Main Thread
                                                This is Lazy Method
                                                This is Lazy Method
                                                This is Lazy Method
 Sleep() used outside for loopà This is Lazy Method
                                                          This is Lazy Method
                                                          This is Lazy Method
                                                          This is Lazy Method
Java.lang.InteruptedException:sleep interrupted

         
Synchronization table for yield(), join() & sleep()
Property
yield()
join()
sleep()
Is it overloaded?
No
Yes
Yes
Is it static?
Yes
No
Yes
Is it final?
No
Yes
No
Is it throws
InterruptedException?

No
Yes
Yes
Is it native?
Yes
No
Sleep(long ms)ànative
Sleep(long ms, int ms)ànot native

Synchronization
‘synchronized’ is the keyword applicable for the methods and blocks. We can’t apply this keyword for variables and classes. If a method declared as synchronized at a time only one thread is allowed to execute that method on the given object. The main advantage of synchronized keyword is we can overcome data inconsistency problem. The main limitation of synchronized keyword is it may create preference problems. Hence if there is no specific requirement it’s not recommended to use synchronized keyword. Every object in java has a unique lock. When ever are using synchronized keyword then object level lock concept will come into picture. If a thread want to execute any synchronized method on the object first it should require the lock of that object. Once a thread got the lock then it is allowed to execute any synchronized method on that object.

While a thread executing a synchronized method on the object, then the remaining threads are not allowed to execute any synchronized method on the same object. But the remaining threads are allowed to execute any non-synchronized method on the same object. Every object in java has unique lock but a thread can acquire more than one lock at a time.

Ex:
class Display
{
public synchronized void wish(String name)
{
for(int i =0;i<10 i="i" o:p="o:p">
{
System.out.print("Hai.......!");
try
{
Thread.sleep(2000);
}
catch (InterruptedException e)
{
}
System.out.println(name);
}
}
}
class MyThread extends Thread
{
Display d;
String name;
MyThread(Display d,String name)
{
this.d = d;
this.name = name;
}
public void run()
{
d.wish(name);
}
}
class SynchronizedDemo
{
public static void main(String arg[])
{
Display d = new Display();
MyThread t1 = new MyThread(d,"YS");
MyThread t2 = new MyThread(d,"Babu");
t1.start();
t2.start();
}
}
O/P:-
Hai………..!YS
Hai………..!YS
Hai………..!YS
Hai………..!YS
Hai………..!YS
Hai………..!Babu
Hai………..!Babu
Hai………..!Babu
Hai………..!Babu
Hai………..!Babu
Hai………..!Babu



If we are not declaring wish method as “synchronized” we will get irregular o/p because both threads will execute simultaneously. If we are declaring wish method as synchronized we will get regular o/p because at a time only one thread is allowed to execute wish method.
Display d1 = new Display();
Display d2 = new Display();
MyThread t1 = new MyThread(d1,"YS");
MyThread t2 = new MyThread(d2,"Babu");
t1.start();
t2.start();
O/P:-
Hai………..!Hai………!YS
Babu
Hai………..!Hai………!YS
Babu
Hai………..!Hai………!YS
Hai………..!Babu
Hai………..!YS
Hai………..!Babu
Hai………..!YS
Hai………..!Babu
Hai………..!YS
Babu

Even though wish method is synchronized we will get irregular o/p only because both threads are operating on different objects.

Class level lock: If a thread want to execute any static synchronized method then compulsory that thread should require class level lock. While a thread executing any static system method then the remaining threads are not allowed to execute any static synchronized method of the same class simultaneously. But the remaining threads are allowed to execute any non-synchronized static methods, synchronized – instance method, non – synchronized instance method simultaneously. Declare static synchronized in display method and try the above example we will get regular p/p because
there is class level lock.


Synchronized Blocks

It is not recommended to declare entire method as synchronized if very few lines of code causes the problem that code we can declare inside Synchronized Block so that we can improve performance of
the system.

Syntax:
synchronized(b)
{
//critical section.
}

Where ‘b’ is an object reference. To get the lock for the current object we can define synchronized block as follows
synchronized(this)
{
//critical section.
}

We can define synchronized block to get class level as follows
synchronized(Display.class) we can define synchronized block either for object references or for class references But not for primitives violation leads to Compile time error.
int i =10;
synchronized(i)
{
//------
}
C.E:- unexpected type
found : int.
required : reference.

Synchronized statement(Only for Interview Purpose):

The statement which are defined in inside synchronized method or synchronized blocks are called ‘synchronized statement’.



Inter Thread Communication
Two threads can communicate with each other by using wait(), notify(), notifyAll(). These methods are available in object class but not in thread class. Because threads are calling these
methods on any object.

We should call these methods only from synchronized area other wise we get runtime exception saying IllegalMonitorStateException.
If a thread executes wait() method it immediately releases the lock of that object(But not all locks) and entered into waiting state.

After giving the notification also the thread releases the lock but may not be immediately.

public final void wait() throws InterruptedException
public final void wait(long ms) throws InterruptedException
public final void wait(long ms, int ns) throws InterruptedException
public final void notify();
public final void notifyAll();

Method                Is lock released
yield()                           X
join()                             X
sleep()                          X
wait()                            |/
notify()                           |/
notifyall()                       |/

Ex:
class ThreadA
{
public static void main(String arg[])throws InterruptedException
{
ThreadB b = new ThreadB();
b.start();
System.out.println("Main Method");
Thread.sleep(100); -------------------1
System.out.println(b.total);
}
}
class ThreadB extends Thread
{
int total = 0;
public void run()
{
System.out.println("Child Starting calculation");
for(int i = 1; i<=100; i++)
{
if(i == 1)System.out.println("in for loop ");
total = total + i;
}
}
}
O/P:-
                   Main Method                                                              Main Method
Using sleepàChild starting calculation    without usingà Child starting calculation 0
                        In for loop                                                                  in for loop
5050                                                                                                                                                           

Here we used sleep() method to give chance to child thread. But we can’t say child thread will finish his work with in given time. So we may get unusually outputs. There is no Guaranteed Output.

Ex:
class ThreadA
{
public static void main(String arg[])throws InterruptedException
{
ThreadB b = new ThreadB();
b.start();
synchronized(b)
{
System.out.println("Main Method calling wait method ");
b.wait();
System.out.println("Main Got Notification");
System.out.println(b.total);
}
}
}
class ThreadB extends Thread
{
int total = 0;
public void run()
{
synchronized(this)
{
System.out.println("Child Starting calculation");
for(int i = 1; i<=100; i++)
{
total = total + i;
}
System.out.println("Child giving notification");
this.notify();
}
}
}
O/P:- Main Method calling wait method
          Child starting calculation
          Child giving notification
          Main got Notification
          5050

Dead Lock

If two threads are waiting for each other forever, then the threads are said to be in “deadlock”. There is no deadlock resolution technique but prevention technique are available

Ex:
Banker’s Algorithm.
Ex:
class A
{
synchronized void foo(B b)
{
System.out.println("Threas 1 entered foo() method");
Using sleep() With out using
try
{
Thread.sleep(600);
}
catch (InterruptedException e)
{
}
System.out.println("Thread 1 is trying to call b.last()");
b.last();
}
synchronized void last()
{
System.out.println("Inside A, This is last() method");
}
}
class B
{
synchronized void bar(A a)
{
System.out.println("Threas 2 entered bar() method");
try
{
Thread.sleep(600);
}
catch (InterruptedException e)
{
}
System.out.println("Thread 2 is trying to call b.last()");
a.last();
}
synchronized void last()
{
System.out.println("Inside B, This is last() method");
}
}
class DeadLock implements Runnable
{
A a = new A();
B b = new B();
DeadLock()
{
Thread t = new Thread(this);
t.start();
b.bar(a);
}
public void run()
{
a.foo(b);
}
public static void main(String arg[])
{
new DeadLock();
}
}
O/P:-
There are 2 entered bar() method
Thread 1 entered foo() method
Thread 2 trying to call b.last()
Thread 1 is trying to call b.last()

DaemonThread

The threads which hare running in the background to provide support for user defined threads are called  “Daemon Thread”. Usually daemon thread are running with low priority but based on our requirement we can increase their priority also.

We can check whether the given thread is daemon or not by using the following thread class thread.

public boolean isDaemon()

we can change the daemon nature of a thread by using setDaemon() method of thread class.

public void setDaemon(Boolean b)

the daemon nature of a thread is inheriting from the parent. i.e if the parent is daemon then the child is also daemon and if the parent is non – daemon then the child is also non – daemon.

After starting a thread we are not allowed to change the daemon nature violation leads to runtime exception saying IllegalThreadStateException.
Ex:
class MyThread extends Thread
{
}
class Test
{
public static void main(String arg[])
{
System.out.println(Thread.currentThread().isDaemon());
MyThread t = new MyThread();
System.out.println(t.isDaemon());
t.setDaemon(true);
System.out.println(t.isDaemon());
t.start();
//t.setDaemon(false); 1
}
}
O/P:-false
          False


If we don’t comment line 1 we will get the IlleagalThreadStateException, see the following o/p.
          False
          False
          True
          Exception in thread “main” java.lang. IlleagalThreadStateException,
          at java.lang.Thread.setDemon(Unkonw source)
            at Test.main(ThreadDemo.java:416)



We can’t change the daemon nature of main thread because it has started already before main() method only. All the daemon threads will be terminated automatically when ever last non – daemon thread terminates.

Ex:
class MyThread extends Thread
{
public void run()
{
for(int i = 0;i<10 i="i" o:p="o:p">
{
System.out.println("Child Thread");
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
}
}
}
}
class DaemonThreadDemo
{
public static void main(String arg[])
{
MyThread t = new MyThread();
t.setDaemon(true); 1
t.start();
System.out.println("The end of main");
}
}
O/P:-
Child Thread
The end of main

If we are commenting line 1, then both child and main threads are non – Daemon, hence they will execute until their completion.

If we are not commenting line 1, then the child thread is daemon and hence it will terminate automatically when ever main() thread terminates.

No comments: