Saturday 3 August 2013

39:Thread class and Runnable interface

Learning Objectives
After completing this session, you will be able to:
‰  Identify Thread class and Runnable interface
‰  Create Thread classes using the earlier concepts
‰  Define Thread Group


Two Ways of Creating and Starting a Thread
The two ways of creating and starting a thread are:
‰  Extending the Thread class
‰  Implementing the Runnable interface
Extending Thread Class
‰  The subclass extends Thread class. The subclass overrides the run() method of
Thread class.
‰  An object instance of the subclass can then be created.
‰  Calling the start() method of the object instance starts the execution of the thread.
Java runtime starts the execution of the thread by calling run() method of object
instance.
Two Schemes of Starting a Thread from a Subclass
‰  The two schemes of starting a thread from a subclass are:
‰  The start() method is not in the constructor of the subclass. The start() method needs
to be explicitly invoked after object instance ofthe subclass is created in order to start
the thread.
‰  The start() method is in the constructor ofthe subclass. Creating an object instance of
the subclass will start the thread.
Scheme 1: start() Method is not in the Constructor of Subclass
1 class PrintNameThread extends Thread {
2 PrintNameThread(String name) {
3 super(name);
4 }

5 public void run() {
6 String name = getName();
7 for (int i = 0; i < 100; i++) {
8 System.out.print(name);
9 }
10 }
11 }
12
13
14 class ExtendThreadClassTest1 {
15 public static void main(String args[]) {
16 PrintNameThread pnt1 =
17 new PrintNameThread("A");
18 pnt1.start(); // Start the first thread
19 PrintNameThread pnt2 =
20 new PrintNameThread("B");
21 pnt2.start(); // Start the second thread
22
23 }
24 }
Scheme 2: start() Method is in a Constructor of the Subclass
1 class PrintNameThread extends Thread {
2 PrintNameThread(String name) {
3 super(name);
4 start(); //runs the thread once instantiated
5 }
6 public void run() {
7 String name = getName();
8 for (int i = 0; i < 100; i++) {
9 System.out.print(name);
10 }
11 }
12 }
13
14 class ExtendThreadClassTest2 {
15 public static void main(String args[]) {
16 PrintNameThread pnt1 =
17 new PrintNameThread("A");
18 PrintNameThread pnt2 =
19 new PrintNameThread("B");
20
21 }
22 }
You can replace the class ExtendThreadClassTest2and its main() method given earlier with the
following code:
14 class ExtendThreadClassTest3 {
15 public static void main(String args[]) {
16 new PrintNameThread("A");
17 new PrintNameThread("B");
18 }
19 }
Runnable Interface
‰  The Runnable interface should be implemented by any class whose instances are
intended to be executed as a thread.
‰  The class must define run() method of no arguments. The run() method is like main()
for the new thread.
‰  The Runnable interface provides the means for a class to be active while not
subclassing Thread. A class that implements Runnable can run without subclassing
Thread by instantiating a Thread instance and passing itself in as the target.
Two Ways of Starting a Thread for a Class that Implements Runnable
The two ways of starting a thread for a class that implements Runnable are:
‰  Caller thread creates Thread object and starts it explicitly after an object instance of
the class that implements Runnable interface is created. The start() method of the
Thread object needs to be explicitly invoked after object instance is created.
‰  The Thread object is created and started within the constructor method of the class
that implements Runnable interface. The caller thread just needs to create object
instances of the Runnable class.
Scheme 1: Caller Thread Creates a Thread Object and Starts it Explicitly
// PrintNameRunnable implements Runnable interface
class PrintNameRunnable implements Runnable {
String name;
PrintNameRunnable(String name) {
this.name = name;
}
// Implementation of the run() defined in the
// Runnable interface.
public void run() {
for (int i = 0; i < 10; i++) {
System.out.print(name);
}
}
}
public class RunnableThreadTest1 {
public static void main(String args[]) {
PrintNameRunnable pnt1 = new PrintNameRunnable("A");
Thread t1 = new Thread(pnt1);
t1.start();
}
}
Scheme 2: Thread Object is Created and Started Within a Constructor
// PrintNameRunnable implements Runnable interface
class PrintNameRunnable implements Runnable {
Thread thread;
PrintNameRunnable(String name) {
thread = new Thread(this, name);
thread.start();
}
// Implementation of the run() defined in the
// Runnable interface.
public void run() {
String name = thread.getName();
for (int i = 0; i < 10; i++) {
System.out.print(name);
}
}
}
public class RunnableThreadTest2 {
public static void main(String args[]) {
// Since the constructor of the PrintNameRunnable
// object creates a Thread object and starts it,
// there is no need to do it here.
new PrintNameRunnable("A");
new PrintNameRunnable("B");
new PrintNameRunnable("C");
}
}
Extending Thread versus Implementing Runnable Interface
Choosing between Thread and Runnable interface is a matter of taste.
Implementing the Runnable interface:
‰  May take more work since you still:
‰  Declare a Thread object
‰  Call the Thread methods on this object
‰  Your class can still extend other class
Extending the Thread class:
‰  Easier to implement
‰  Your class can no longer extend any other class
ThreadGroup Class
‰  A thread group represents a set of threads.
‰  In addition, a thread group can also include other thread groups. The thread groups
form a tree in which every thread group except the initial thread group has a parent.
‰  A thread is allowed to access information about its own thread group, but not to
access information about the parent thread group of the thread group or any other
thread groups.
Example: ThreadGroup
1 // Start three threads
2 new SimpleThread("Jamaica").start();
3 new SimpleThread("Fiji").start();
4 new SimpleThread("Bora Bora").start();
5
6 ThreadGroup group
7 = Thread.currentThread().getThreadGroup();
8
9 Thread[] tarray = new Thread[10];
10 int actualSize = group.enumerate(tarray);
11 for (int i=0; i<actualSize;i++){
12 System.out.println("Thread " +
13 tarray[i].getName() + " in thread group "
14 + group.getName());
15 }
Try It Out
Problem Statement:
Write a program that illustrates the usage of Runnable interface in the creation of threads.
Code:
class ThreadUsingRunnableApp {
public static void main(String args[]) {
Thread thread1 = new Thread(new MyClass("thread1: "));
Thread thread2 = new Thread(new MyClass("thread2: "));
thread1.start();
thread2.start();
boolean thread1IsAlive = true;
boolean thread2IsAlive = true;
do {
if (thread1IsAlive && !thread1.isAlive()) {
thread1IsAlive = false;
System.out.println("Thread 1 is dead.");
}
Refer File Name: ThreadUsingRunnableApp.javato obtain soft copy of the program code
Refer File Name: ThreadUsingRunnableApp_output_on_two_executions.txt for the console
output on two different occasions
How It Works:
‰  The advantage of using the Runnable interface is that your class does not need to
extend the Thread class. Instead,your class can extend some other required class, if
desired.
‰  This is a very helpful feature when you create multithreaded applets.
‰  The only disadvantage to this approach is that you have to do a little more work to
create and execute your threads.
Tips and Tricks:
How good is the idea of making a subclass of Thread and override the run() method of thread
instead of using a separate Runnable implementation? [Thread t = new Thread(); // no Runnable]
Solution:
‰  Yes, that is another way of making your own thread. Remember that there are two
things to be noticed, which are the Thread and the job of the thread. From an OO
view, those two are very separate activities, and belong to separate classes.
‰  The only time you want to subclass or extend the Thread class is if you are making a
new and more specific type of Thread. In other words, if you think of the Thread as the
worker, then do not extend the Thread class unless you need more specific worker
behaviors.
‰  But if all you need is a new job to be run by a Thread or worker, then implement
Runnable in a separate class that is specific to job and not specific to worker.
‰  This is a design issue and not a performance orlanguage issue. It is perfectly legal to
subclass Thread and override then run() method, but it is rarely a good idea.
Summary
‰  Threads can be created by extending Thread and overriding the public void run()
method.
‰  Thread objects can also be created by calling the Thread constructor that takes a
Runnable argument. The Runnable object is said to be the target of the thread.
‰  You can call start() on a Thread object only once. If start() is called more than once on
a Thread object, it will throw a RuntimeException.
‰  It is legal to create many Thread objects using the same Runnable object as the
target.
‰  When a Thread object is created, it does not become a thread of executionuntil its
start() method is invoked. When a Thread object exists but hasn’t been started, it is in
the newstate and is not considered alive.
Test Your Understanding
1.Write the different forms of constructor of the Thread class.
2.What useful purpose does the isAlive() method of the Thread class serve?
3.How can you assign priority to a thread? Does the priority value always lie between one
and 10?

No comments:

Post a Comment