UET TAXILA
Lab Manual
OOP
3rd Semester Lab-13: Multithreading in Java
Laboratory 13:
Statement Purpose:
At the end of this lab, the students should be able to:
• Implement Exception Handling with Method Overriding and using throws keyword
in Java.
• Implement Multithreading concepts in Java.
Throws Keyword:
The Java throws keyword is used to declare an exception. It gives an information to the programmer
that there may occur an exception so it is better for the programmer to provide the exception handling
code so that normal flow can be maintained.
Now we will see the example of java throws clause which describes that checked exceptions can be
propagated by throws keyword.
Rule: If you are calling a method that declares an exception, you must either catch or declare the
exception.
Throws Keyword: C1
You handle the exception
import java.io.*;
class M{
void method() throws IOException
{
throw new IOException ("device error");
}
}
public class TestThrowsC1 {
public static void main(String[] args) {
try {
M m=new M();
m.method();
}catch(Exception e)
{
System.out.println("Exception handled");
}
System.out.println("Normal Flow");
}
}
Output:
Exception handled
Normal Flow
Engr. Sidra Shafi Lab-13 1
3rd Semester Lab-13: Multithreading in Java
Throws Keyword: C2
You declare the exception
A)In case you declare the exception, if exception does not occur, the code will be executed fine.
import java.io.IOException;
class M1{
void method() throws IOException
{
System.out.println("device operation performed");
}
}
public class TestThrows_C2 {
public static void main(String[] args) throws IOException {
M1 m=new M1();
m.method();
System.out.println("Normal Flow");
}
}
Output:
device operation performed
Normal Flow
Throws Keyword: C3
B)In case you declare the exception if exception occurs, an exception will be thrown at runtime
because throws does not handle the exception.
import java.io.IOException;
class M2{
void method() throws IOException
{
throw new IOException ("device error");
}
}
public class Testthrows_C3 {
public static void main(String[] args) throws IOException {
M2 m=new M2();
m.method();
System.out.println("Normal Flow");
} }
Output:
Engr. Sidra Shafi Lab-13 2
3rd Semester Lab-13: Multithreading in Java
Throws Keyword: C4
import java.io.IOException;
class M3{
void method() throws IOException
{
throw new IOException ("device error");
}
}
public class Testthrows_C4 {
public static void main(String[] args) throws IOException {
try {
M3 m=new M3();
m.method();
}catch(Exception e)
{
System.out.println("Exception handled");
}
System.out.println("Normal Flow");
}
}
Output:
Exception handled
Normal Flow
Exception Handling with Method Overriding
When Exception handling is involved with Method overriding, ambiguity occurs. The compiler gets
confused as which definition is to be followed. Such problems were of two types:
Problem 1: If The SuperClass doesn’t declare an exception:
In this problem, two cases arise:
Case 1: If SuperClass does not declare any exception and subclass declare checked exception
import java.io.*;
class SuperClass {
// SuperClass doesn't declare any exception
void method()
{
System.out.println("SuperClass");
}
}
// SuperClass inherited by the SubClass
class Subclass extends SuperClass {
// method() declaring Checked Exception IOException
void method() throws IOException
{
// IOException is of type Checked Exception
// so the compiler will give Error
Engr. Sidra Shafi Lab-13 3
3rd Semester Lab-13: Multithreading in Java
System.out.println("SubClass");
}
// Driver code
SuperClass s = new SubClass();
s.method();
}
}
Output:
Case 2: If SuperClass doesn’t declare any exception and SubClass declare Unchecked exception
import java.io.*;
class SuperClass1 {
// SuperClass doesn't declare any exception
void method()
{
System.out.println("SuperClass");
}
}
// SuperClass inherited by the SubClass
class Subclass2 extends SuperClass1 {
// method() declaring Unchecked Exception ArithmeticException
void method() throws ArithmeticException
{
// ArithmeticException is of type Unchecked Exception
// so the compiler won't give any error
System.out.println("SubClass");
}
// Driver code
public static void main(String args[])
{
SuperClass1 s = new Subclass2();
s.method();
}
}
Output:
SubClass
Problem 2: If The SuperClass declares an exception:
In this problem also, three cases arise:
Engr. Sidra Shafi Lab-13 4
3rd Semester Lab-13: Multithreading in Java
• Case 1: If SuperClass declares an exception and SubClass declares exceptions other than the
child exception of the SuperClass declared Exception
Example:
import java.io.*;
class SuperClass3 {
// SuperClass declares an exception
void method() throws RuntimeException
{
System.out.println("SuperClass");
}
}
// SuperClass inherited by the SubClass
class Subclass3 extends SuperClass3 {
// SubClass declaring an exception
// which are not a child exception of RuntimeException
void method() throws Exception
{
// Exception is not a child exception
// of the RuntimeException
// So the compiler will give an error
System.out.println("SubClass");
}
// Driver code
public static void main(String args[])
{
SuperClass3 s = new Subclass3();
s.method();
}
}
Output:
Case 2: If SuperClass declares an exception and SubClass declares a child exception of the
SuperClass declared Exception.
import java.io.*;
class SuperClass4 {
// SuperClass declares an exception
void method() throws RuntimeException
Engr. Sidra Shafi Lab-13 5
3rd Semester Lab-13: Multithreading in Java
{
System.out.println("SuperClass");
}
}
// SuperClass inherited by the SubClass
class Subclass4 extends SuperClass4 {
// SubClass declaring a child exception
// of RuntimeException
void method() throws ArithmeticException
{
// ArithmeticException is a child exception
// of the RuntimeException
// So the compiler won't give an error
System.out.println("SubClass");
}
// Driver code
public static void main(String args[])
{
SuperClass4 s = new Subclass4();
s.method();
}
}
Output:
SubClass
Case 3: If SuperClass declares an exception and SubClass declares without exception.
import java.io.*;
class SuperClass5 {
// SuperClass declares an exception
void method() throws IOException
{
System.out.println("SuperClass");
}
}
// SuperClass inherited by the SubClass
class Subclass5 extends SuperClass5 {
// SubClass declaring without exception
void method()
{
System.out.println("SubClass");
}
// Driver code
public static void main(String args[])
{
SuperClass5 s = new Subclass5();
try {
s.method();
Engr. Sidra Shafi Lab-13 6
3rd Semester Lab-13: Multithreading in Java
} catch (IOException e) {
e.printStackTrace();
}
}
}
Output:
SubClass
Conclusion for Handling such Exceptions: Hence, following conclusions can be derived from the
above examples:
1. If SuperClass does not declare an exception, then the SubClass can only declare unchecked
exceptions, but not the checked exceptions.
2. If SuperClass declares an exception, then the SubClass can only declare the child exceptions of
the exception declared by the SuperClass, but not any other exception.
3. If SuperClass declares an exception, then the SubClass can declare without exception.
Multithreading:
A thread is a single sequential flow of control within a program. It is also called a lightweight
process (sub-process).
The Java Virtual Machine allows an application to have multiple threads of execution running
concurrently."
Java supports thread-based multitasking. The advantages of thread-based multitasking as
compared to process-based multitasking are given below:
1. Threads share the same address space.
2. Context-switching between threads is normally inexpensive.
3. Communication between threads is normally inexpensive.
1. Creating Java Threads:
In Java, there are two ways to create threaded programs:
1. extend the Thread class:
class MyThread extends Thread {
......
}
2. implement the interface Runnable:
class MyThread implements Runnable {
......
}
Either of these two approaches may be used. Sometimes it is not possible to extend the Thread
class, because you must extend some other class. Remember that Java does not support multiple
inheritance. In those cases where it is not possible to extend the Thread class, you need to
implement the Runnable interface.
Engr. Sidra Shafi Lab-13 7
3rd Semester Lab-13: Multithreading in Java
To create new threads in this case, simply use:
MyThread t = new MyThread();
Extending the Thread Class:
The steps for creating a thread by using the first mechanism are:
1. Create a class by extending the Thread class and override the run() method:
class MyThread extends Thread {
public void run() { //
thread body of execution
}
}
2. Create a thread object:
MyThread thr1 = new MyThread();
3. Start Execution of created thread:
thr1.start();
An example program illustrating creation and invocation of a thread object is given below:
Example:
class MyThread extends Thread {
public void run() {
System.out.println("Hi there");
}
}
public class TestThread0 {
public static void main (String arg[]) {
MyThread t1, t2;
t1 = new MyThread();
t2 = new MyThread();
t1.start();
t2.start();
} }
Output:
Implementing the Runnable Interface:
The steps for creating a thread by using the second mechanism are:
1. Create a class that implements the interface Runnable and override run() method:
class MyThread implements Runnable {
… public void run() {
// thread body of execution
}}
2. Creating Object:
Engr. Sidra Shafi Lab-13 8
3rd Semester Lab-13: Multithreading in Java
MyThread myObject = new MyThread();
3. Creating Thread Object:
Thread thr1 = new Thread(myObject);
4. Start Execution: thr1.start();
An example program illustrating creation and invocation of a thread object is given below:
Example:
/*A simple program creating and invoking a thread object by implementing Runnable interface. */
class MyThread implements Runnable {
public void run() {
System.out.println(“ this thread is running ... ”);
}}
class ThreadEx2 {
public static void main(String [] args ) {
Thread t = new Thread(new MyThread());
t.start();
}}
2. Starting and Stopping Java Threads:
The Thread class has three primary methods that are used to control a thread:
public void start()
public void run()
public final void stop()
• The start() method prepares a thread to be run;
• the run() method actually performs the work of the thread - it serves as the main routine
for the thread;
• and the stop() method halts the thread.
The thread dies when the run() method terminates or when the thread's stop() method is
invoked.
The class that extends Thread must redefine the run() method of Thread.
The run() method is called automatically at runtime as necessary, once you have called start().
To stop a thread t, you may call t.stop();
However, it is recommended to never stop a thread using the stop method (deprecated). Let a
thread stop when the thread function returns and determine when the thread function should
return using boolean variables, as necessary.
3. Naming Java Threads:
It is often useful to give different threads in the same class names, so you can tell them apart.
The constructor that allows you to do that is:
public Thread(String name)
Engr. Sidra Shafi Lab-13 9
3rd Semester Lab-13: Multithreading in Java
This is normally called from the constructor of a subclass (your own), like this:
class MyThread extends Thread {
MyThread(String name) {
super(name);
}
public void run() {
System.out.println(this.getName());
...
}
}
Java Thread setName() method:
The setName() method of thread class is used to change the name of the thread.
public final void setName(String a) a => It shows the new name for the thread.
This method does not return any value.
public class Thread_setName extends Thread
{
public void run()
{
System.out.println("running...");
}
public static void main(String args[])
{
// creating two threads
Thread_setName t1=new Thread_setName();
Thread_setName t2=new Thread_setName();
// start of thread
t1.start();
t2.start();
// change the thread name
t1.setName("Sidra Shafi");
t2.setName("OOP Lab");
// print the thread after changing
System.out.println("After changing name of t1: "+t1.getName());
System.out.println("After changing name of t2: "+t2.getName());
}
}
Output:
Engr. Sidra Shafi Lab-13 10
3rd Semester Lab-13: Multithreading in Java
The getName() method of the Thread class returns the name of the thread. The following
program now distinguishes the output of different threads:
Example:
class MyThread extends Thread {
public MyThread (String s)
{
super(s);
}
public void run() {
System.out.println("Hello, I am "+ getName());
}
}
public class TestThread {
public static void main (String arg[]) {
MyThread t1, t2;
t1 = new MyThread ("Thread #1");
t2 = new MyThread ("Thread #2");
t2.start();
t1.start();
} }
Output:
4. Threads Priority:
It is possible to control the priority of the threads by using the Java APIs. The
Thread.setPriority(…) method serves this purpose. The Thread class provides 3 constants value
for the priority: MIN_PRIORITY = 1, NORM_PRIORITY = 5, MAX_PRIORITY = 10. The
priority range of the thread should be between the minimum and the maximum number. In most
cases, thread schedular schedules the threads according to their priority (known as preemptive
scheduling). But it is not guaranteed because it depends on JVM specification that which
scheduling it chooses. The following example shows how to alter the order of the thread by
changing its priority.
Example:
/* ThreadPriorityDemo.java:
A program which shows altering order of threads by changing priority. */
class A extends Thread {
public void run() {
System.out.println("Thread A started");
for(int i = 1; i <= 4; i++) {
System.out.println("\t From ThreadA: i= " + i);
}
System.out.println("Exit from A");
} }
Engr. Sidra Shafi Lab-13 11
3rd Semester Lab-13: Multithreading in Java
class B extends Thread {
public void run() {
System.out.println("Thread B started");
for(int j = 1; j <= 4; j++) {
System.out.println("\t From ThreadB: j= " + j);
}
System.out.println("Exit from B");
} }
class C extends Thread {
public void run() {
System.out.println("Thread C started");
for(int k = 1; k <= 4; k++) {
System.out.println("\t From ThreadC: k= " + k);
}
System.out.println("Exit from C");
} }
public class ThreadPriorityDemo {
public static void main(String args[]) {
A threadA = new A();
B threadB = new B();
C threadC = new C();
threadC.setPriority(Thread.MAX_PRIORITY);
threadB.setPriority(threadA.getPriority() + 1);
threadA.setPriority(Thread.MIN_PRIORITY);
System.out.println("Started Thread A");
threadA.start();
System.out.println("Started Thread B");
threadB.start();
System.out.println("Started Thread C");
threadC.start();
System.out.println("End of main thread");
}
}
Output:
Engr. Sidra Shafi Lab-13 12
3rd Semester Lab-13: Multithreading in Java
5. Threads Methods:
Joining:
· Suppose you want to wait for another worker thread to complete its run()
· Send the join() message to the worker thread object -- worker.join() -- causes the current
running thread to block efficiently until worker finishes its run
· We must handle the InterruptedException that join() may throw. Java will break us out of the
join if we are interrupted by another thread, so really there are two ways to get out of a join() -
the other thread finishes, or we are interrupted.
Example:
public class ThreadDemo implements Runnable {
public void run() {
Thread t = Thread.currentThread();
System.out.print(t.getName());
//checks if this thread is alive
System.out.println(", status = " + t.isAlive());
}
public static void main(String args[]) throws Exception {
Thread t = new Thread(new ThreadDemo());
// this will call run() function
t.start();
// waits for this thread to die
t.join();
System.out.print(t.getName());
Engr. Sidra Shafi Lab-13 13
3rd Semester Lab-13: Multithreading in Java
//checks if this thread is alive
System.out.println(", status = " + t.isAlive());
}
}
Output:
Lab Task
Write a program named MathThreads.java that perform concurrent mathematical
operations like finding Sin, Cos and Tan of an angle using multiple threads. Although the
master thread can continue its execution, in this case, it needs to make sure that all
operations are completed before combining individual results.
z= sin(45)+cos(60)+tan(30)
(Use Math Class-> It is in java.lang package) Marks: 10
******************
Engr. Sidra Shafi Lab-13 14