Thursday, October 13, 2011

Threads Part1: An introduction

A thread in computer science is short for a thread of execution. A thread is a single sequential flow of control within a program (i.e., process). Threads are a way for a process to split itself into multiple simultaneously running tasks. Threads are lightweight processes because they run within the context of a full-blown program and takes advantage of the resources allocated for that program and the program's environment. Threads are similar to process, but differ in the way that they share resources.
Java virtual machine can support many threads of execution at once. These threads independently execute code that operates on values and objects residing in a shared main memory. Threads may be supported by having many hardware processors (where threads are executed on separate processors), by time-slicing a single hardware processor (where a single processor switches between different threads giving the illusion that they are all executing at the same time), or by time-slicing many hardware processors. There is always at least one thread within every Java program: the main() method of the class which was given as a parameter to the Java interpreter.

Difference between a user thread and daemon thread. The daemon threads purpose is to give services to the user threads which are created by the user to perform the long running task (mostly for not blocking the ui or to do something in background ).The main() method of the application is a user thread. Threads created by a user are user thread ,you can also create the Daemon thread by explicitly calling the setDaemon(true) on a Thread object.One important point here is that setDaemon() method must be called before the thread is started .Once all the user threads are terminated then only JVM will terminate not in the other way if there are Daemon threads running but no user threads then JVM will close the running application .There should be atleast one user thread(main thread is a user thread )running for the JVM not to close the application.


There are two ways of implementing threading in JAVA
1) By extending java.lang.Thread class, or
2) By implementing java.lang.Runnable interface.
Before we go into implementation details I just like to cover when we use thread? so we use thread if we want some part of code is executed parallel and we put that code inside run() method of either Thread class or Runnable interface.
Actually public void run () method is defined in Runnable interface and since java.lang.Thread class implements Runnable interface it gets this method automatically.


//implementing Thread by extending Thread class
class MyThread extends Thread{
public void run(){
System.out.println("I am executing by Thread: " + Thread.currentThread().getName());
}
}

//implementing Thread by implementing Runnable interface
class MyRunnable implements Runnable{
public void run(){
System.out.println("I am executing by Thread: " + Thread.currentThread().getName());
}
}
//starting Thread
Thread mythread = new MyThread();
mythread.setName("T1");
Thread myrunnable = new Thread(new MyRunnable(),"T2");
mythread.start();
myrunnable.start();


Thread will not start until you call the start() method of java.lang.Thread class. When we call start () method Java Virtual machine execute run () method of that Thread class into separate Thread other than calling thread. Anybody guess what will happen if we call the run() method directly instead of calling start() method ?
run() method will simply be executed in the same Thread and new Thread will not be created. Another follow up question would be what will happen if you call start () method twice in same Thread object e.g

mythread.start();
mythread.start();// this line will throw IllegalThreadStateException


Difference between mythread.start() & mythread.run()?
• If we call mythread.start(), it will create a new Thread and that thread is responsible for execution of run().
• If we call mythread.run(), no new thread will create, the main thread only will execute run(), just like a normal method.
• In case of mythread.start() output we can’t expect
• In case of mythread.run() output first it ll run the code in the run function in the main thread .
Thread class start():-

public void start()
{
1. Registering our thread with the thread scheduler then only thread scheduler allocate CPU and memory type of resources for this new thread also.
2. calls run() // you can think of it as a call back invoked by the jvm
}



The thread is in the "new" state, once it is constructed. In this state, it is merely an object in the heap, without any system resources allocated for execution. From the "new" state, the only thing you can do is to invoke the start() method, which puts the thread into the "runnable" state. Calling any method besides the start() will trigger an IllegalThreadStateException.

The start() method allocates the system resources necessary to execute the thread, schedules the thread to be run, and calls back the run() once it is scheduled. This put the thread into the "runnable" state. However, most computers have a single CPU and time-slice the CPU to support multithreading. Hence, in the "runnable" state, the thread may be running or waiting for its turn of the CPU time.
The thread enters the "not-runnable" state when one of these events occurs:
The sleep() method is called to suspend the thread for a specified amount of time and yield control to the other threads.

The wait() method is called to wait for a specific condition to be satisfied.
The thread is blocked and waiting for an I/O operation to be completed.
For the "non-runnable" state, the thread becomes "runnable" again:
If the thread was put to sleep, the specified sleep time expired or the sleep was interrupted via a call to the interrupt() method.
If the thread was put to wait via wait(), its notify() or notifyAll() method was invoked to inform the waiting thread that the specified condition had been fulfilled and the wait was over.
If the thread was blocked for an I/O operation, the I/O operation has been completed.
A thread is in a "dead" state, only when the run() method terminates naturally and exits.

The method isAlive() can be used to test whether the thread is alive. isAlive() returns false if the thread is "new" or "dead". It returns true if the thread is "runnable" or "not-runnable".
JDK 1.5 introduces a new Thread.getState() method. This method returns an enum of type Thread.State, which takes a constant of {NEW, BLOCKED, RUNNABLE, TERMINATED, WAITING}.
NEW: the thread has not yet started.
RUNNABLE:
WAITING:
BLOCKED: the thread is blocked waiting for a monitor lock.
TIMED_WAITING: the thread is waiting with a specified waiting time.
TERMINATED:

Methods in Thread Class
The methods available in Thread class include:
public void start(): Begin a new thread. JVM calls back the run() method of this class. The current thread continues.
public void run(): to specify the execution flow of the new thread. When run() completes, the thread terminates.
public static sleep(long millis) throws InterruptedException: Temporarily suspend the thread and yield control to other thread for the given milliseconds. Method sleep() is thread-safe as it does not release its monitors. The method throws InterruptedException if it is awaken before the specified timing (via a call to interrupt() method). This is a static method and commonly used to pause the current thread so that the other threads can have a chance to execute. For example:
try {
// suspend for 0.1 sec and give other threads a chance to run
sleep(100);
} catch (InterruptedException ex) {}
public void interrupt(): Interrupt the sleep() method.
public boolean isAlive(): Return false if the thread is new or dead. Returns true if the thread is "runnable" or "not runnable".
public void setPriority(int p): Set the priority-level of the thread, which is implementation dependent.
public void yield(): suspend the current thread to allow other threads to run.
The stop(), suspend(), and resume() methods have been deprecated in JDK 1.4, because they are not thread-safe, due to the release of monitors. See JDK API documentation for more discussion.

What is the difference between implementing Runnable and extending Thread?
One difference between implementing Runnable and extending Thread is that by extending Thread, each of your threads has a unique object associated with it, whereas implementing Runnable, many threads can share the same object instance.
"Which way of implementing Thread is better? Extending Thread class or implementing Runnable method?

In my opinion implementing Runnable is better because in Java we can only extend one class so if we extend Thread class we can not extend any other class while by implementing Runnable interface we still have that option open with us.
Second reason which make sense to me is more on OOPS concept according to OOPS if we extend a class we provide some new feature or functionality , So if the purpose is just to use the run() method to define code its better to use Runnable interface.
e.g


public class Espresso {
public static void main (String[] args) {
Runner r = new Runner();

Thread t1 = new Thread(r, "Thread A");
Thread t2 = new Thread(r, "Thread B");
Thread s1 = new Mythread("Thread C");
Thread s2 = new Mythread("Thread D");

t1.start();
t2.start();
s1.start();
s2.start();

}
}

class Runner implements Runnable {
private int counter;
public void run() {
try {
for (int i = 0; i != 2; i++) {
System.out.println(Thread.currentThread().getName() + ": "
+ counter++);
Thread.sleep(1000);
}
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
}

class Mythread extends Thread {
private int counter;
Mythread(String name) {
super(name);
}
public void run() {
try {
for (int i = 0; i != 2; i++) {
System.out.println(Thread.currentThread().getName() + ": "
+ counter++);
Thread.sleep(1000);
}
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
}


output
Thread A: 0
Thread B: 1
Thread C: 0
Thread D: 0
Thread C: 1
Thread B: 2
Thread A: 3
Thread D: 1

No comments:

Post a Comment