Unit3 OOPS

Download as pdf or txt
Download as pdf or txt
You are on page 1of 78

II Year/III Semester

CS3391 - Object Oriented Programming

Course WorkBook-Unit-3

RIT - Java Centre of Excellence


Index Sheet - Coursework Book

SlNo Content Pages

1 Course Notes 1-38

2 Content Beyond the Syllabus 39-45

3 Assignment 46

4 Question Bank(Part-A,B,C) 47-49

5 Multiple Choice Questions 50-56

6 Practice Programs 57-75


UNIT – III

EXCEPTION HANDLING AND MULTITHREADING

Exception Handling basics- Multiple catch Clauses – Nested try statements-Java’s Built-in Exceptions
– User defined Exception-Multithreaded Programming: Java Thread Model- Creating a Thread and
Multiple Threads-Inter Thread Communication-Suspending-Resuming, and Stopping Threads–
Multithreading - Wrappers – Auto boxing

1. EXCEPTION HANDLING BASICS

1. What happens when the statement: int value = 25/0; is executed? (MAY/JUN 2016,
APR/MAY 2017, APR/MAY 2019)
2. Define runtime exceptions. (NOV/DEC 2018)
3. What is the use of assert keyword? (NOV/DEC 2018, NOV/DEC 2018)
4. Explain the types of exceptions in java. (NOV/DEC 2019)
5. Write a Java program to create user define exception. (APR/MAY 2017)
6. What is exception handling? Explain with an example exception handling in java.
(APR/MAY 2018)
7. Explain ‘Divide by zero’ Exception with an example. Java program. (APR/MAY 2019)
8. State the use of try block in Java exception handling. (NOV/DEC 2017)
9. Throw an exception if the matrices cannot be multiplied and handle it using a user
defined exception. (NOV/DEC 2017)
10. Discuss in detail on how exceptions are handled with an appropriate example.
(NOV/DEC 2019)

1.1 Difference between error and exception

Errors indicate serious problems and abnormal conditions that most applications should not try to
handle. Error defines problems that are not expected to be caught under normal circumstances by
our program. For example memory error, hardware error, JVM error etc.
Exceptions are conditions within the code. A developer can handle such conditions and take
necessary corrective actions. Few examples
• DivideByZero exception

• NullPointerException

• ArithmeticException

• ArrayIndexOutOfBoundsException

An exception (or exceptional event) is a problem that arises during the execution of a program. When
an Exception occurs the normal flow of the program is disrupted and the program/Application
terminates abnormally, which is not recommended, therefore, these exceptions are to be handled. If
an exception is raised, which has not been handled by programmer then program execution can get
terminated and system prints a non-user-friendly error message.
Ex: Exception in thread "main"
java.lang.ArithmeticException: / by zero at ExceptionDemo.main
(ExceptionDemo.java:5)
ExceptionDemo :
The class name main : The method name
ExceptionDemo.java : The filename
java: 5: Line number

An exception can occur for many different reasons. Following are somescenarios where an exception
occurs.
• A user has entered an invalid data.

• A file that needs to be opened cannot be found.

• A network connection has been lost in the middle of communications orthe JVM has run out
of memory.

1.2 Exception Hierarchy

All exception classes are subtypes of the java.lang.Exception class. Theexception class is a subclass
of the Throwable class.

Keywords used in Exception handling

There are 5 keywords used in java exception handling.

1. try A try/catch block is placed around the code that might generate an

exception. Code within a try/catch block is referred to as protected code.


2. catch A catch statement involves declaring the type of exception we are trying

to catch.
3. finally A finally block of code always executes, irrespective of occurrence of an

Exception.
4. throw It is used to execute important code such as closing connection, stream

etc. throw is used to invoke an exception explicitly.


5. throws throws are used to postpone the handling of a checked exception.

Syntax : //Example-predefined Exception - for


//ArrayindexoutofBounds Exception public
try
{ class ExcepTest
//Protected code {
} public static void main(String args[])
{
catch(ExceptionType1 e1) int a[] = new int[2];
{ try
//Catch block {
} System.out.println("Access element three :" + a[3]);
}
catch(ExceptionType2 e2) catch(ArrayIndexOutOfBoundsException e)
{ {
//Catch block System.out.println("Exception thrown :" + e);
} }
catch(ExceptionType3 e3)
{ finally
//Catch block {
}
a[0] = 6;
finally
System.out.println("First element value: " + a[0]);
{
//The finally block always executes. }
}
System.out.println("The finally statement is executed");
}
}

Output
Exception thrown :
java.lang.ArrayIndexOutOfBoundsException:3
First element value: 6
The finally statement is executed
Note : here array size is 2 but we are trying to access 3rd
element.

Uncaught Exceptions
This small program includes an expression that intentionally causes a divide-by- zero error:
class Exc0 {
public static void main(String args[])
{
int d = 0;
int a = 42 / d;
}}

When the Java run-time system detects the attempt to divide by zero, it constructs a new exception
object and then throws this exception. This causes the execution of Exc0 to stop, because once an
exception has been thrown, it must be caught by an exception handler and dealt with immediately
Any exception that is not caught by your program will ultimately be processed by the default handler.
The default handler displays a string describing the exception, prints a stack trace from the point at
which the exception occurred, and terminates the program.

Here is the exception generated when this example is executed:

java.lang.ArithmeticException: / by zero at Exc0.main(Exc0.java:4)

Stack Trace
Stack Trace is a list of method calls from the point when the application was started to the
point where the exception was thrown. The most recent method calls are at the top. A stacktrace is a
very helpful debugging tool. It is a list of the method calls that the application was in the middle of
when an Exception was thrown. This is very useful because it doesn't only show you where the error
happened, but also how the program ended up in that place of the code. Using try and Catch to guard
against and handle a run-time error, simply enclose the code that you want to monitor inside a try
block. Immediately following the try block, include a catch clause that specifies the exception type
that you wish to catch. A try and its catch statement form a unit. The following program includes a try
block and a catch clause that processes the ArithmeticException generated by the division-by-zero
error

class Exc2
{
public static void main(String args[])
{
int d, a;
try {
// monitor a block of code.
d = 0;
a = 42 / d;
System.out.println("This will not be printed.");
} catch (ArithmeticException e)
{ // catch divide-by-zero error
System.out.println("Division by zero.");
}
System.out.println("After catch statement.");
}
}
This program generates the following output: Division by zero. After catch statement. The call to
println( ) inside the try block is never executed. Once an exception is thrown, program control
transfers out of the try block into the catch block.

Assertion

Assertion is a statement in java. It can be used to test your assumptions about the program. While
executing assertion, it is believed to be true. If it fails, JVM will throw an error named AssertionError.
It is mainly used for testing purpose.

Advantage of Assertion:

It provides an effective way to detect and correct programming errors.

Syntax of using Assertion:

There are two ways to use assertion.


First way is:
assert expression;

Second way is:


assert expression1 : expression2;

Simple Example of Assertion in java:

import java.util.Scanner;

class AssertionExample{
public static void main( String args[] ){

Scanner scanner = new Scanner( System.in );


System.out.print("Enter ur age ");

int value = scanner.nextInt();


assert value>=18:" Not valid";

System.out.println("value is "+value);
}
}

Output:
Enter ur age 11
Exception in thread "main" java.lang.AssertionError: Not valid

Categories of Exceptions

Checked exceptions −A checked exception is an exception that occurs at the compile time, these are
also called as compile time exceptions. These exceptions cannot simply be ignored at the time of
compilation, the programmer should take care of (handle) these exceptions.

Unchecked exceptions − An unchecked exception is an exception that occurs at the time of


execution. These are also called as Runtime Exceptions. These include programming bugs, such as
logic errors or improper use of an API. Runtime exceptions are ignored at the time of compilation.

Common scenarios where exceptions may occur:

They are as follows:


1) Scenario where ArithmeticException occurs If we divide any number by zero, there occurs an
ArithmeticException.
int a=50/0;//ArithmeticException

2) Scenario where NullPointerException occurs If we have null value in any variable, performing any
operation by the variable occurs an NullPointerException.
String s=null; System.out.println(s.length());//NullPointerException

3) Scenario where ArrayIndexOutOfBoundsException occurs If you are inserting any value in the
wrong index, it would result ArrayIndexOutOfBoundsException as shown below:
int a[]=new int[5];
a[10]=50; //ArrayIndexOutOfBoundsException

1. 2 Multiple catch Clauses


In some cases, more than one exception could be raised by a single piece of code. To handle
this type of situation, you can specify two or more catch clauses, each catching a different type of
exception. When an exception is thrown, each catch statement is inspected in order, and the first one
whose type matches that of the exception is executed. After one catch statement executes, the others
are bypassed, and execution continues after the try/catch block.

The following example traps two different exception types:

// Demonstrate multiple catch statements.

class MultiCatch
{
public static void main(String args[])
{
try {
int a = args.length;
System.out.println("a = " + a);
int b = 42 / a;
int c[] = { 1 };
c[42] = 99;
}
catch(ArithmeticException e)
{
System.out.println("Divide by 0: " + e);
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("Array index oob: " + e);
}
System.out.println("After try/catch blocks."); } }
Here is the output generated by running it both ways:

C:\>java MultiCatch
a=0
Divide by 0: java.lang.ArithmeticException: / by zero After try/catch blocks.
C:\>java MultiCatch TestArg
a=1
Array index oob: java.lang.ArrayIndexOutOfBoundsException:42 After try/catch blocks.

1.3 Nested try Statements

The try statement can be nested. That is, a try statement can be inside the block of another try.
Each time a try statement is entered, the context of that exception is pushed on the stack. If an inner
try statement does not have a catch handler for a particular exception, the stack is unwound and the
next try statement’s catch handlers are inspected for a match. This continues until one of the catch
statements succeeds, or until all of the nested try statements are exhausted. If no catch statement
matches, then the Java run-time system will handle the exception.

// An example of nested try statements.


class NestTry {
public static void main(String args[]) {
try {
int a = args.length;
/* If no command-line args are present, the following statement will generate a divide-by-zero
exception. */
int b = 42 / a;
System.out.println("a = " + a);
try {
// nested try block
/* If one command-line arg is used, then a divide-by-zero exception will be generated by the
following code. */
if(a==1)
a = a/(a-a);
// division by zero
/* If two command-line args are used, then generate an out-of-bounds exception. */
if(a==2)
{
int c[] = { 1 };
c[42] = 99;
// generate an out-of-bounds exception
} } catch(ArrayIndexOutOfBoundsException e)
{ System.out.println("Array index out-of-bounds: " + e); }
} catch(ArithmeticException e)
{ System.out.println("Divide by 0: " + e); } } }

C:\>java NestTry
Divide by 0: java.lang.ArithmeticException: / by zero
C:\>java NestTry One
a=1 Divide by 0: java.lang.ArithmeticException: / by zero
C:\>java NestTry One Two
a=2 Array index out-of-bounds: java.lang.ArrayIndexOutOfBoundsException:42

throw
it is possible for your program to throw an exception explicitly, using the throw statement. The
general form of throw is shown here:

throw ThrowableInstance;

Here, ThrowableInstance must be an object of type Throwable or a subclass of Throwable.


Primitive types, such as int or char, as well as non-Throwable classes, such as String and Object,
cannot be used as exceptions. There are two ways you can obtain a Throwable object: using a
parameter in a catch clause, or creating one with the new operator. The flow of execution stops
immediately after the throw statement; any subsequent statements are not executed. The nearest
enclosing try block is inspected to see if it has a catch statement that matches the type of exception. If
it does find a match, control is transferred to that statement. If not, then the next enclosing try
statement is inspected, and so on. If no matching catch is found, then the default exception handler
halts the program and prints the stack trace
// Demonstrate throw.
class ThrowDemo
{
static void demoproc()
{
try
{
throw new NullPointerException("demo");
}
catch(NullPointerException e)
{
System.out.println("Caught inside demoproc.");
throw e; // rethrow the exception
} }
public static void main(String args[])
{
try
{
demoproc();
}
catch(NullPointerException e)
{ System.out.println("Recaught: " + e); } } }

Here is the resulting output:


Caught inside demoproc.
Recaught: java.lang.NullPointerException: demo

throws
If a method is capable of causing an exception that it does not handle, it must specify this
behaviour so that callers of the method can guard themselves against that exception. You do this by
including a throws clause in the method’s declaration. A throws clause lists the types of exceptions
that a method might throw. This is necessary for all exceptions, except those of type Error or
RuntimeException, or any of their subclasses. All other exceptions that a method can throw must be
declared in the throws clause.

This is the general form of a method declaration that includes a throws clause:
type method-name(parameter-list) throws exception-list
{ // body of method }
Here, exception-list is a comma-separated list of the exceptions that a method can throw.
class ThrowsDemo {
static void throwOne() throws IllegalAccessException
{
System.out.println("Inside throwOne.");
throw new IllegalAccessException("demo");
}
public static void main(String args[])
{ try { throwOne(); }
catch (IllegalAccessException e) {
System.out.println("Caught " + e); } } }

Here is the output generated by running this example program:


inside throwOne caught java.lang.IllegalAccessException: demo

finally
The finally keyword is designed to address this contingency. finally creates a block of code that will
be executed after a try/catch block has completed and before the code following the try/catch block.
The finally block will execute whether or not an exception is thrown. If an exception is thrown, the
finally block will execute even if no catch statement matches the exception. Any time a method is
about to return to the caller from inside a try/catch block, via an uncaught exception or an explicit
return statement, the finally clause is also executed just before the method returns. This can be useful
for closing file handles and freeing up any other resources that might have been allocated at the
beginning of a method with the intent of disposing of them before returning. The finally clause is
optional.
// Demonstrate finally.
class FinallyDemo {
// Through an exception out of the method.
Static void procA()
{
try
{ System.out.println("inside procA");
throw new RuntimeException("demo");
}
finally {
System.out.println("procA's finally"); } }
// Return from within a try block.
static void procB()
{
try {
System.out.println("inside procB");
return;
} finally { System.out.println("procB's finally"); } }
// Execute a try block normally.
static void procC()
{
try { System.out.println("inside procC"); }
finally { System.out.println("procC's finally"); } }
public static void main(String args[]) {
try { procA(); }
catch (Exception e) { System.out.println("Exception caught");
}
procB();
procC();
}
}

Here is the output generated by the preceding program:


inside procA
procA’s finally
Exception caught
inside procB
procB’s finally
inside procC
procC’s finally

1.4 Java’s Built-In Exceptions


Java defines several exception classes inside the standard package java.lang.
The most general of these exceptions are subclasses of the standard type RuntimeException. Since
java.lang is implicitly imported into all Java programs, most exceptions derived from
RuntimeException are automatically available.
Java defines several other types of exceptions that relate to its various class libraries.
Java Unchecked RuntimeException

S.No. Exception & Description

1 ArithmeticException
Arithmetic error, such as divide-by-zero.

2 ArrayIndexOutOfBoundsException
Array index is out-of-bounds.

3 ArrayStoreException
Assignment to an array element of an incompatible type.

4 ClassCastException
Invalid cast.

5 IllegalArgumentException
Illegal argument used to invoke a method.

6 IllegalMonitorStateException
Illegal monitor operation, such as waiting on an unlocked thread.

7 IllegalStateException
Environment or application is in incorrect state.

8 IllegalThreadStateException
Requested operation not compatible with the current thread state.

9 IndexOutOfBoundsException
Some type of index is out-of-bounds.

10 NegativeArraySizeException
Array created with a negative size.

11 NullPointerException
Invalid use of a null reference.

12 NumberFormatException
Invalid conversion of a string to a numeric format.

13 SecurityException
Attempt to violate security.

14 StringIndexOutOfBounds
Attempt to index outside the bounds of a string.

15 UnsupportedOperationException
An unsupported operation was encountered.

Java Checked Exceptions

S.No. Exception & Description

1 ClassNotFoundException
Class not found.

2 CloneNotSupportedException
Attempt to clone an object that does not implement the Cloneable interface.

3 IllegalAccessException
Access to a class is denied.

4 InstantiationException
Attempt to create an object of an abstract class or interface.

5 InterruptedException
One thread has been interrupted by another thread.
6 NoSuchFieldException
A requested field does not exist.

7 NoSuchMethodException
A requested method does not exist.

1.5 User-defined Exceptions


All exceptions must be a child of Throwable. If we want to write a checked exception that is
automatically enforced bythe Handle, we need to extend the Exception class.

User defined exception needs to inherit (extends) Exception class inorder to act as an
exception throw keyword is used to throw such exceptions.

class MyOwnException extends Exception


{
public MyOwnException(String msg)

super(msg);
}

class EmployeeTest
{

static void employeeAge(int age) throws MyOwnException


{
if(age < 0)

throw new MyOwnException("Age can't be lessthan zero");


else
System.out.println("Input is valid!!");
}

public static void main(String[] args)

{
try

{
employeeAge(-2);

catch (MyOwnException e)
{

e.printStackTrace();
}}}

Advantages of Exception Handling

• Exception handling allows us to control the normal flow of the program by using exception
handling in program.

• It throws an exception whenever a calling method encounters an error providing that the
calling method takes care of that error.

• It also gives us the scope of organizing and differentiating between different error types using
a separate block of codes. This is done with thehelp of try-catch blocks.

2. MULTITHREADED PROGRAMMING

1. Sketch the lifecycle of a thread. (APR/MAY 2019)


2. What is multithreading? (MAY/JUN 2016, APR/MAY 2017, APR/MAY 2018,
NOV/DEC 2018)
3. Create a Bank database application program to illustrate the use of multithreads
(NOV/DEC 2018)
4. Describe the various state of thread. (NOV/DEC 2019)
5. “Thread is a light weight process” – Comment. (NOV/DEC 2019)
6. What is a thread? Explain multithreading and multitasking in detail. (NOV/DEC
2019)
7. What is synchronization? Explain the different types of synchronization in java.
(NOV/DEC 2019)
8. Create a simple real life application program in Java to Illustrate the use of
multithreads. (NOV/DEC 2019)
9. Explain about thread synchronization with an example. (APR/MAY 2017)
10. Describe in detail about Multithreaded programming. (APR/MAY 2019, NOV/DEC
2017)

Thread

A thread is a single sequential (separate) flow of control within program.Sometimes, it is called an


execution context or light weight process.

Multithreading
Multithreading is a conceptual programming concept where a program (process)is divided into two
or more subprograms (process), which can be implemented at the same time in parallel. A
multithreaded program contains two or more partsthat can run concurrently. Each part of such a
program is called a thread, and each thread defines a separate path of execution.
Multitasking

Executing several tasks simultaneously is called multi-tasking.There are 2 types of multi-tasking


• Process-based multitasking
• Thread-based multi-tasking
Process-based multi-tasking
Executing various jobs together where each job is a separate independent operation is called
process-based multi-tasking.

Thread-based multi-tasking
Executing several tasks simultaneously where each task is a separate independent part of the same
program is called Thread-based multitasking and each independent part is called Thread. It is best
suitable for the programmatic level. The main goal of multi-tasking is to make or do a better
performance of the system by reducing response time

Multithreading vs Multitasking

Multithreading is to execute multiple Multitasking is to run multiple processes on


threads in a process concurrently. a computerconcurrently.
In Multithreading, the CPU switches In Multitasking, the CPU switches between
between multiple threads in the same multiple processes to complete the
process. execution.
In Multithreading, resources are shared In Multitasking, resources are sharedamong
among multiple threads in a process. multiple processes.

Multithreading is light-weight andeasy to Multitasking is heavy-weight and harder to


create. create.

2.1 Java Thread Model

Life Cycle of Thread - A thread can be in any of the five following states

1) Newborn State
When a thread object is created a new thread is born and said to be in Newborn state.
2) Runnable State
If a thread is in this state it means that the thread is ready for execution and waiting for the
availability of the processor. If all threads in queue are of same priority, then they are given
time slots for execution in round robin fashion.
3) Running State
It means that the processor has given its time to the thread for execution. A thread keeps
running until the following conditions occurs.

Thread gives up its control on its own and it can happen in the following situations
• A thread gets suspended using suspend () method which can only be revived with resume()
method

• A thread is made to sleep for a specified period of time using sleep(time) method, where
time in milliseconds

• A thread is made to wait for some event to occur using wait () method. In this case a thread
can be scheduled to run again using notify ()method.

• A thread is pre-empted by a higher priority thread

4) Blocked State

If a thread is prevented from entering into runnable state and


subsequently running state, then a thread is said to be in Blocked state.

5) Dead State
A runnable thread enters the Dead or terminated state when it completes its task or
otherwise

Life cycle of Thread


The Main Thread
When we run any java program, the program begins to execute its code starting from the main
method. Therefore, the JVM creates a thread to start executing the code present in main method. This
thread is called as main thread.Although the main thread is automatically created, you can control it
by obtaining a reference to it by calling currentThread() method.

Two important things to know about main thread are,

• It is the thread from which other threads will be produced.

• main thread must be always the last thread to finish execution.

class MainThread
{

public static void main(String[] args)

Thread t1=Thread.currentThread();
t1.setName("MainThread");

System.out.println("Name of thread is "+t1); }}

Output:

Name of thread is Thread[MainThread,5,main]

2.2 Creating a Thread and Multiple Threads

Thread Can Be Implemented In Two Ways

• Implementing Runnable Interface


• Extending Thread Class

Create Thread by Implementing Runnable


The easiest way to create a thread is to create a class that implements the Runnable interface. To
implement Runnable, a class need only implement a single method called run()

Example:
public class ThreadSample implements Runnable
{
public void run()
{
try {
for (int i = 5; i > 0; i--)
{
System.out.println("Child Thread" + i);
Thread.sleep(1000);
}
}
catch (InterruptedException e) {
System.out.println("Child interrupted");
}
System.out.println("Exiting Child Thread"); }
}
public class MainThread {
public static void main(String[] arg) {
ThreadSample d = new ThreadSample();
Thread s = new Thread(d);
s.start();
try
{
for (int i = 5; i > 0; i--)
{
System.out.println("Main Thread" + i);
Thread.sleep(5000);
}}
catch (InterruptedException e) {
System.out.println("Main interrupted"); }
System.out.println("Exiting Main Thread"); }}

Extending Thread Class

The second way to create a thread is to create a new class that extends Thread, and then to
create an instance of that class. The extending class must override the run( ) method, which is the
entry point for the new thread. It must also call start( ) to begin execution of the new thread.
Example:
public class ThreadSample extends Thread {
public void run() {
try {
for (int i = 5; i > 0; i--) {
System.out.println("Child Thread" + i);
Thread.sleep(1000); }
} catch (InterruptedException e) {
System.out.println("Child interrupted"); }
System.out.println("Exiting Child Thread");
}}
public class MainThread {
public static void main(String[] arg) {
ThreadSample d = new ThreadSample(); d.start(); try {
for (int i = 5; i > 0; i--) {
System.out.println("Main Thread" + i);
Thread.sleep(5000); }
} catch (InterruptedException e) {
System.out.println("Main interrupted"); }
System.out.println("Exiting Main Thread"); }
}

Thread priority
Each thread have a priority. Priorities are represented by a number between 1 and 10. 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.
3 constants defined in Thread class:
public static int MIN_PRIORITY
public static int NORM_PRIORITY
public static int MAX_PRIORITY
Default priority of a thread is 5 (NORM_PRIORITY).
The value of MIN_PRIORITY is 1 and the value of MAX_PRIORITY is 10.
Example :
public class MyThread1 extends Thread {
MyThread1(String s) {
super(s);
start(); }
public void run() { for(int i=0;i<5;i++) {
Thread cur=Thread.currentThread();
cur.setPriority(Thread.MAX_PRIORITY);
int p=cur.getPriority();
System.out.println("Thread Name"+Thread.currentThread().getName());
System.out.println("Thread Priority"+cur); }
}}
class MyThread2 extends Thread
{ MyThread2(String s)
{ super(s);
start(); }
public void run()
{ for(int i=0;i<5;i++) {
Thread cur=Thread.currentThread();
cur.setPriority(Thread.MIN_PRIORITY);
System.out.println(cur.getPriority());
int p=cur.getPriority(); System.out.println("Thread Name"+Thread.currentThread().getName());
System.out.println("Thread Priority"+cur);
}
}}
public class ThreadPriority { public static void main(String[] args) {
MyThread1 m1=new MyThread1("MyThread1");
MyThread2 m2=new MyThread2("MyThread2"); }
}

Synchronizing Threads
• Synchronization in java is the capability to control the access of multiple threads to any shared
resource.
• Java Synchronization is better option where we want to allow only one thread to access the
shared resource
General Syntax :
synchronized(object) { //statement to be synchronized }

Why use Synchronization


The synchronization is mainly used
• To prevent thread interference.
• To prevent consistency problem.

Types of Synchronization
• Process Synchronization
• Thread Synchronization

There are two types of thread synchronization mutual exclusive and inter-thread communication.
1. Mutual Exclusive
• Synchronized method.
• Synchronized block.
• static synchronization.

2.Cooperation (Inter-thread communication in java)

Synchronized method
• If you declare any method as synchronized, it is known as synchronized method.
• Synchronized method is used to lock an object for any shared resource.
• When a thread invokes a synchronized method, it automatically acquires the lock for that
object and releases it when the thread completes its task.

Example of synchronized method


package Thread;
public class SynThread {
public static void main(String args[]) {
share s = new share();
MyThread m1 = new MyThread(s, “Thread1”);
MyThread m2 = new MyThread(s, "Thread2");
MyThread m3 = new MyThread(s, "Thread3"); }
}
class MyThread extends Thread {
share s;
MyThread(share s, String str) {
super(str);
this.s = s;
start();
}
public void run()
{
s.doword(Thread.currentThread().getName()); }
}
class share {
public synchronized void doword(String str)
{
for (int i = 0; i < 5; i++) {
System.out.println("Started:" + str);
try {
Thread.sleep(1000); }
catch (Exception e)
{
}}}}
Synchronized block.
• Synchronized block can be used to perform synchronization on any specific resource of the
method.
• Suppose you have 50 lines of code in your method, but you want to synchronize only 5 lines,
you can use synchronized block.
• If you put all the codes of the method in the synchronized block, it will work same as the
synchronized method.
Example of synchronized block
class Table
{
void printTable(int n)
{ synchronized(this)
{//synchronized block
for(int i=1;i<=5;i++)
{
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
} } }//end of the method
}
class MyThread1 extends Thread
{
Table t;
MyThread1(Table t)
{ this.t=t; }
public void run()
{ t.printTable(5);
} }
class MyThread2 extends Thread
{ Table t;
MyThread2(Table t)
{ this.t=t; }
public void run(){ t.printTable(100); } }
public class TestSynchronizedBlock1
{ public static void main(String args[])
{ Table obj = new Table();//only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start(); } }
Static synchronization
If you make any static method as synchronized, the lock will be on the class not on object.
Example of static synchronization
In this example we are applying synchronized keyword on the static method to perform static
synchronization.
class Table{
synchronized static void printTable(int n)
{ for(int i=1;i<=10;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){}
}}
}
class MyThread1 extends Thread
{ public void run()
{ Table.printTable(1); } }
class MyThread2 extends Thread
{ public void run(){ Table.printTable(10); } }
class MyThread3 extends Thread{ public void run(){ Table.printTable(100); } }
class MyThread4 extends Thread{ public void run(){ Table.printTable(1000); } }
public class TestSynchronization4{
public static void main(String t[]){
MyThread1 t1=new MyThread1();
MyThread2 t2=new MyThread2();
MyThread3 t3=new MyThread3();
MyThread4 t4=new MyThread4();
t1.start();
t2.start();
t3.start();
t4.start(); }
}

2.3 Inter-thread communication

Inter-thread communication or Co-operation is all about allowing synchronized threads to


communicate with each other. Inter-thread communication is a mechanism in which a thread is
paused running in its critical section and another thread is allowed to enter (or lock) in the same
critical section to be executed. It is implemented by following methods of Object class:

• wait()
• notify()
• notifyAll()

wait() - tells calling thread to give up monitor and go to sleep until some other thread enters the
same monitor and call notify.
notify() - wakes up a thread that called wait() on same object.
notifyAll() - wakes up all the thread that called wait() on same object.

wait() sleep()
wait() method releases the lock sleep() method doesn't release the lock.
It is the method of Object class It is the method of Thread class
It is the non-static method It is the static method
It should be notified by notify() or notifyAll() after the specified amount of time, sleep is
methods completed.

Example of inter thread communication in java

Class Customer{
int amount=10000;
synchronized void withdraw(int amount){
System.out.println("going to withdraw...");
if(this.amount<amount){
System.out.println("Less balance; waiting for deposit...");
try{
wait();
}catch(Exception e){}
}
this.amount-=amount;
System.out.println("withdraw completed..."); }
synchronized void deposit(int amount)
{
System.out.println("going to deposit...");
this.amount+=amount;
System.out.println("deposit completed... ");
notify();
}
}
class Test{
public static void main(String args[]){
final Customer c=new Customer();
new Thread(){
public void run(){
c.withdraw(15000);
}
}.start();
new Thread(){
public void run()
{
c.deposit(10000);
}
}.start();
}}

Daemon Thread in Java

Daemon thread in java is a service provider thread that provides services to the user thread. Its life
depend on the mercy of user threads i.e. when all the user threads dies, JVM terminates this thread
automatically.

Example:

public class TestDaemonThread1 extends Thread{


public void run()
{if(Thread.currentThread().isDaemon())
{//checking for daemon thread
System.out.println("daemon thread work");
}
else{
System.out.println("user thread work");
}
}
public static void main(String[] args){
TestDaemonThread1 t1=new TestDaemonThread1();
//creating thread
TestDaemonThread1 t2=new TestDaemonThread1();
TestDaemonThread1 t3=new TestDaemonThread1();
t1.setDaemon(true);//now t1 is daemon thread
t1.start();//starting threads
t2.start();
t3.start();
}
}
Thread Group
Java provides a convenient way to group multiple threads in a single object. In such way, we can
suspend, resume or interrupt group of threads by a single method call.

Constructors of ThreadGroup class


There are only two constructors of ThreadGroup class.
1.ThreadGroup (String name)-creates a thread group with given name.
2.ThreadGroup (ThreadGroup parent, String name)-creates a thread group with given parent group
and name.

Important methods of ThreadGroup class

There are many methods in ThreadGroup class.

A list of important methods are given below.


1)int activeCount() - returns no. of threads running in current group.
2)int activeGroupCount() - returns a no. of active group in this thread group.
3)void destroy() - destroys this thread group and all its sub groups.
4)String getName() - returns the name of this group.
5)ThreadGroup getParent() - returns the parent of this group.
6)void interrupt() - interrupts all threads of this group.
7)void list() - prints information of this group to standard console.
Let's see a code to group multiple threads.
ThreadGroup tg1 = new ThreadGroup("Group A");
Thread t1 = new Thread(tg1,new MyRunnable(),"one");
Thread t2 = new Thread(tg1,new MyRunnable(),"two");
Thread t3 = new Thread(tg1,new MyRunnable(),"three");
Now all 3 threads belong to one group. Here, tg1 is the thread group name, MyRunnable is the class
that implements Runnable interface and "one", "two" and "three" are the thread names. Now we can
interrupt all threads by a single line of code only.
Thread.currentThread().getThreadGroup().interrupt();
ThreadGroup Example
public class ThreadGroupDemo implements Runnable
{ public void run() {
System.out.println(Thread.currentThread().getName()); }
public static void main(String[] args)
{ThreadGroupDemo runnable = new ThreadGroupDemo();
ThreadGroup tg1 = new ThreadGroup("Parent ThreadGroup"); Thread t1 = new Thread(tg1,
runnable,"one");
t1.start();
Thread t2 = new Thread(tg1, runnable,"two");
t2.start();
Thread t3 = new Thread(tg1, runnable,"three");
t3.start();
System.out.println("Thread Group Name: "+tg1.getName());
tg1.list();
}}
Output:
One two three Thread Group Name:
Parent ThreadGroup java.lang.ThreadGroup[name=Parent ThreadGroup,maxpri=10]
Thread[one,5,Parent ThreadGroup]
Thread[two,5,Parent ThreadGroup]
Thread[three,5,Parent ThreadGroup]

2.4 Multithreading

Multithreading in Java executes a complex process by running a collection of threads simultaneously.


Each thread belongs to the Java.lang.Thread class. The thread class overrides the run() method and
executes the process.
Methods of Multithreading in Java

start() The start method initiates the execution of a thread

The currentThread method returns the reference to the currently executing


currentThread()
thread object.

run() The run method triggers an action for the thread

isAlive() The isAlive method is invoked to verify if the thread is alive or dead

sleep() The sleep method is used to suspend the thread temporarily

The yield method is used to send the currently executing threads to standby
yield()
mode and runs different sets of threads on higher priority

suspend() The suspend method is used to instantly suspend the thread execution

The resume method is used to resume the execution of a suspended thread


resume()
only

The interrupt method triggers an interruption to the currently executing


interrupt()
thread class

destroy() The destroy method is invoked to destroy the execution of a group of threads

stop() The stop method is used to stop the execution of a thread

Example for Multithreading in Java


The following is an example based on multithreading in Java using the runnable interface.
//Code
package multithreading;
class ThreadCount extends Thread{
ThreadCount(){
super("Overriding Thread Class");
System.out.println("New thread created" + this);
start();
}
public void run(){ //Run Method
try{
for (int i=0 ;i<10;i++){
System.out.println("New thread created" + this);
Thread.sleep(1500);
}
}
catch(InterruptedException e){
System.out.println("Currently executing thread is interrupted");
}
System.out.println("Currently executing thread run is terminated" );
}
}
public class MultiThreading{
public static void main(String args[]){
ThreadCount C = new ThreadCount();
try{
while(C.isAlive()){
System.out.println("Main Method Thread will be alive, until it's Child Thread stays alive");
Thread.sleep(2500); //Sleep method
}
}
catch(InterruptedException e){
System.out.println("Main Method thread is interrupted");
}
System.out.println("Main Method's thread run is terminated" );
}
}
Output:
New thread createdThread[Overriding Thread Class,5,main]
Main Method Thread will be alive, until it's Child Thread stays alive
New thread createdThread[Overriding Thread Class,5,main]
New thread createdThread[Overriding Thread Class,5,main]
Main Method Thread will be alive, until it's Child Thread stays alive
New thread createdThread[Overriding Thread Class,5,main]
New thread createdThread[Overriding Thread Class,5,main]
Main Method Thread will be alive, until it's Child Thread stays alive
New thread createdThread[Overriding Thread Class,5,main]
Main Method Thread will be alive, until it's Child Thread stays alive
New thread createdThread[Overriding Thread Class,5,main]
New thread createdThread[Overriding Thread Class,5,main]
Main Method Thread will be alive, until it's Child Thread stays alive
New thread createdThread[Overriding Thread Class,5,main]
New thread createdThread[Overriding Thread Class,5,main]
Main Method Thread will be alive, until it's Child Thread stays alive
New thread createdThread[Overriding Thread Class,5,main]
Main Method Thread will be alive, until it's Child Thread stays alive
Currently executing thread run is terminated
Main Method's thread run is terminated

3. WRAPPERS

1. Write a program to convert String from back to its data types using parseXXX()
methods?
2. Can a Byte object be cast to a double value?
3. Name the eight primitive Java types.
4. Why do we need wrapper classes?
5. What is autoboxing?

Wrapper classes in Java provides a way to wrap or represent the value of primitive data types as an
object. By creating an object to the wrapper class, a data field is created and, in this field, we can store
the value of a primitive data type. It also includes methods to unwrap the objects back into the
primitive data types. It is one of the classes provided in the java.lang package and all of the primitive
wrapper classes in Java are immutable.

• Primitive Data Types cannot be directly used as objects that's why Wrapper classes come into
picture.
• Generic classes work with objects and don't support Primitives. As a result, Wrapper classes
are needed as they convert primitive data types into objects and objects are really important
if we need to modify the arguments passed in a method. Now, let's discuss in detail about the
Wrapper Classes.
• The Java programming language provides the java.lang package which has classes that are
fundamental to the design and the most important classes among them are Object and Class.
• So, Java wrapper classes wraps or represents the values of primitive data types as an object.
When an object is created to a wrapper class, it contains a field which can store the primitive
data types.
• The object of one type contains a field of that particular type only, which means a Double type
of object contains double type of field only, representing that value so that a reference to it can
be stored in a variable of reference type.

Below are the Primitive Data Types and their corresponding Wrapper classes:
Primitive Data Type Wrapper Class
char Character
byte Byte
short Short
int Integer
long Long
float Float
double Double
boolean Boolean

Need of Wrapper Classes in Java

• Whenever the primitive types are required as an object, wrapper classes can be used.
• Wrapper classes also include methods to unwrap the object and give back the primitive data
type.
• In java.util package, the classes handle only objects and that's why in this case wrapper class
helps.
• In the Collection framework, Data Structures such as ArrayList stores only the objects and not
the primitive types

// Invalid
ArrayList<int> exampleList = new ArrayList<>();

// Valid
ArrayList<Integer> exampleList = new ArrayList<>();

• For the methods that support object like creation from other types such as String.

Integer num = new Integer("55");

• Wrapper classes are also used for synchronization in multithreading. As objects are needed to
achieve the synchronization process where we ensure that the shared resource will be used
by only one thread at a time.

3.1 Flow of the Wrapper Class in Java

In Java Wrapper Classes, the object is created with fields or properties in which the primitive
data types can be stored.
Creating Wrapper Objects

Wrapper object can be created using the wrapper class and its constructor by passing the value to it.

Syntax:

ClassName objectName = new ClassName(argument);

Example:

Integer number = new Integer(77); // int


Integer number2 = new Integer("77"); // String
Float number3 = new Float(77.0); // double argument
Float number4 = new Float(77.0f); // float argument
Float number5 = new Float("77.0f"); // String
Character c1 = new Character('S'); // Only char constructor
Character c2 = new Character(1234); // COMPILER ERROR
Boolean b = new Boolean(true); // value stored - true

Using Wrapper class only (instead of the primitive type)

We can create an instance of wrapper classes without their constructors as well. We can create a
variable of data type same as the class name of wrapper classes and assign a raw value to it without
using the new operator as shown below:

Syntax:
ClassName objectName = value;

Example:
public class CreatingWrapperObject {

public static void main(String[] args) {


// Creating the object using the wrapper class
// without passing the value to the constructor

// Object intValue of type Integer will store the value 10 as int


Integer intValue = 10;
Double doubleValue = 8.89;
Character charValue = 'S';

// Printing the values using the created objects


System.out.println(intValue);
System.out.println(doubleValue);
System.out.println(charValue);
}
}

Output:
10
8.89
S
Example: Converting an Integer to a String wrapper class object using the toString()method:

public class CreatingWrapperObject2 {

public static void main(String[] args) {


// Creating the object using the Wrapper class
Integer intValue = 1000;

// Converting the integer value to String and


// assigning it to stringObject
String stringObject = intValue.toString();

// Printing the length of the String using length() method


System.out.println(stringObject.length());
}
}

Output:

Using valueOf Static methods

By using the static valueOf method, a Wrapper object can be created.

Syntax:

ClassName objectName = ClassName.valueOf(argument(s));

// Multiple parameters may be present

Example:

Integer hundred = Integer.valueOf("100");

// 100 is stored in variable. Here, Integer.valueOf(String str) is used.

Integer seven = Integer.valueOf("111", 2);

// binary 111 is converted to 7.

// Here, Integer.valueOf(String str, int base) is used.

Features of Java Wrapper Classes

Value modification in function

We have the 'call by value' function in Java programming, using this we can modify the arguments
passed into a method with the help of the objects converted from primitive data types. If the argument
is not constant and it needs to be modified, we can pass the objects and can modify the values
accordingly.
Synchronization

To support Java synchronization an object is needed. It operates into objects in multi-threading. As


for the identification of the blocks in multi-threading, objects are required.

Synchronized blocks in Java are marked with the synchronized keyword. This block in Java is
synchronized on some object. All blocks that are synchronized on the same object can only have one
thread executing inside them at a time. All other threads attempting to enter the synchronized block
are blocked until the thread inside the synchronized block exits the block.

Serialization

To implement the serialization, the object is converted within streams. The object can be regrated
using the java wrapper classes. Basically, the class of the object must implement Serializable interact
directly or indirectly.

java.util package

The implementaton of the utility classes in the **java.util **package is to match with the objects and
wrapper classes help to achieve the same as well.

Collection framework

Java collection framework classes such as ArrayList, HashSet, Vector, LinkedList, etc. store only
objects i.e. reference types and not primitive types. So objects are instances of wrapper classes and
that's why it helps for this.

3.2 Methods Supported by the Wrapper Classes

All of the numeric wrapper classes are subclasses of the abstract class Number such as Byte, Integer,
Double, Short, Float, Long. Some of the frequently used methods that all subclasses of the Number
class implements are listed in the following table:

Method Method Description


Converts the value of a Numeric object such as Integer, Float or Double to the specified
typeValue()
primitive data type and returns the value
compareTo() Compares this Number object to the argument passed
equals() Determines whether this Number object is equal to the argument
valueOf() Returns an Integer object holding the value of the specified primitive data type value
toString() Returns a String object representing the value of specified Integer type argument
parseInt() Returns an Integer type value of a specified String representation
decode() Decodes a String into an integer
min() Returns the smaller value after comparison of the two arguments
max() Returns the larger value after comparison of the two arguments
round() Returns the closest round off long or int value as per the method return type

The following methods are used to get the value associated with the corresponding wrapper object:
intValue(), byteValue(), shortValue(), longValue(), floatValue(), doubleValue(), charValue(),
booleanValue().
This example will output the same result as the example above:

public class Main {

public static void main(String[] args) {

Integer myInt = 5;

Double myDouble = 5.99;

Character myChar = 'A';

System.out.println(myInt.intValue());

System.out.println(myDouble.doubleValue());

System.out.println(myChar.charValue());

}}

There are more such methods which are implemented by the subclasses of the Number class. The
above table lists only few of them.

Java Wrapper classes Example

1. Primitive Types to Wrapper Objects


class Main {
public static void main(String[] args) {

// create primitive types


int a = 5;
double b = 5.65;

//converts into wrapper objects


Integer aObj = Integer.valueOf(a);
Double bObj = Double.valueOf(b);

if(aObj instanceof Integer) {


System.out.println("An object of Integer is created.");
}

if(bObj instanceof Double) {


System.out.println("An object of Double is created.");
}
}
}

Output:
An object of Integer is created.
An object of Double is created.
Explanation:

In the above example, we have used the valueOf() method to convert the primitive types into objects.

Here, we have used the instanceof operator to check whether the generated objects are of Integer or
Double type or not.

However, the Java compiler can directly convert the primitive types into corresponding objects. For
example,

int a = 5;
// converts into object
Integer aObj = a;

double b = 5.6;
// converts into object
Double bObj = b;
This process is known as auto-boxing which we have already discussed. In which the conversion
happens for primitive types into objects internally. Like here in the above example, the primitive type
value of a is converted into object aObj. Internally, the Integer.valueOf(a) is used by the compiler and
aObj is assigned to the value of a that is 5.

2. Wrapper Objects into Primitive Types

class Main {
public static void main(String[] args) {

// creates objects of wrapper class


Integer aObj = Integer.valueOf(23);
Double bObj = Double.valueOf(5.55);

// converts into primitive types


int a = aObj.intValue();
double b = bObj.doubleValue();

System.out.println("The value of a: " + a);


System.out.println("The value of b: " + b);
}
}

Output:

The value of a: 23
The value of b: 5.55
Explanation:
In the above example, we have used the intValue() and doubleValue() method to convert the Integer
and Double objects into corresponding primitive types.

However, the Java compiler can automatically convert objects into corresponding primitive types. For
example,

Integer aObj = Integer.valueOf(2);


// converts into int type
int a = aObj;

Double bObj = Double.valueOf(5.55);


// converts into double type
double b = bObj;
This process is known as unboxing which we have already discussed.

3. Custom Wrapper Class in Java.


As the Java Wrapper classes wrap the primitive data types. Likewise, we can also create custom
wrapper class in Java which wraps a primitive data type.

// Creating the custom wrapper class


class SpeedWrapperClass {

private int speed;

SpeedWrapperClass() {}

SpeedWrapperClass(int speed) {
this.speed = speed;
}

public int getVehicleSpeed() {


return speed;
}

public void setVehicleSpeed(int speed) {


this.speed = speed;
}

@Override
public String toString() {
return Integer.toString(speed);
}
}

// Testing the custom wrapper class


public class TestJavaWrapperClass {

public static void main(String[] args) {


SpeedWrapperClass speedValue = new SpeedWrapperClass(100);
System.out.println(speedValue);
}
}
Output:

100
Explanation:

Here, we have created a custom wrapper class that is SpeedWrapperClass() and to set the value of
speed we have also created constructors.
Now, when we created an instance of the custom wrapper class and passed the integer value it worked
as Integer wrapper class which wraps the int value of 100 and set the speed as 100.
In a way, we have a data member field of type int speed which holds the primitve int value passed as
argument to the constructor.
Advantages of Java Wrapper Class in Java
In Java, there can be various scenarios where we need to use objects instead of primitive data types.
For example, while working with collections. As we can see in the below example we need to use
Integer not the primitive int.
// error
ArrayList<int> list = new ArrayList<>();

// runs perfectly
ArrayList<Integer> list = new ArrayList<>()
We can use the objects of the wrapper class and store them as a null value. In real time scenario
applications, the values can be null and hence, we need to store null values.
Objects of classes such as Character and Integer are pointers: the actual number stored in the bytes
that are that reference variable's value represents an address in memory. So, it is possible and
meaningful to set that number to an address that goes nowhere. This is exactly what null is. A
primitive like int or char, however, has a number that is interpreted as a number (integer, or ASCII
code), and there's no way to make it "not a number" because all that the memory can possibly store
is numbers.

// generates an error
int a = null;

// runs perfectly
// More intuitive in real world applications
Integer a = null;

A wrapper type allows a primitive to operate in more advanced ways. An integer can be used in
various ways. For example, we can create a class Hour which will give a meaning to the number
associated with it.
The primitive types just operate with value, the wrapper class provides it with a name. For example,
int as Integer, char as Character, etc. It means that int only specifies the range and type of the value
but by creating the object with wrapper class Integer it will be given a reference variable which points
to the object in the heap memory.
3.3 Autoboxing

Autoboxing is when the Java compiler performs the automatic conversion of the primitive data types
to the object of their corresponding wrapper classes. For example, converting an int to Integer, a
double to Double, etc.
The Java compiler applies autoboxing when a primitive value is:
Passed as a parameter to a method that expects an object of the corresponding wrapper class.
Assigned to a variable of the corresponding wrapper class.

For example:
//Autoboxing example of int to Integer and char to Char
public class AutoboxingExample {
public static void main(String args[]) {
char ch = 's';
//Autoboxing- primitive to Character object conversion
Character s = ch;
int a = 50;
// Converting int into Integer explicitly
Integer first = Integer.valueOf(a);
// Autoboxing, now compiler will write Integer.valueOf(a)
// internally and hence, doesn't generate an error
Integer second = a;
System.out.println(a);
System.out.println(first);
System.out.println(second);
}
}

Output:
50
50
50

Explanation:
Here, the output is 50 for all as:
The ‘a’ variable is assigned to int value 50.
The first variable is assigned to the value of ‘a’ that is 50. Only in such a case, primitive data type int
is converted into Integer explicitly.
The second variable will also have the value of ‘a’ that is 50 as due to autoboxing the compiler
internally performs the conversion automatically (implicit conversion).

3.4 Unboxing
It is just the opposite process of autoboxing. Unboxing is automatically converting an object of a
wrapper type (Integer, for example) to its corresponding primitive (int) value.

The Java compiler applies unboxing when an object of a wrapper class is:
Passed as a parameter to a method that expects a value of the corresponding primitive type.
Assigned to a variable of the corresponding primitive type.
For example:

//Unboxing example of Integer to int and Character to char


public class UnboxingExample {

public static void main(String args[]) {


Character ch = 's';

//Unboxing - Character object to primitive conversion


char s = ch;

Integer a = new Integer(5);

//Converting Integer to int explicitly


int first = a.intValue();

//Unboxing, now compiler will write a.intValue() internally


int second = a;

System.out.println(a);
System.out.println(first);
System.out.println(second);
}
}
Output:
5
5
5
Explanation:

Here, the output for all is 5 as:


The object a is created with Integer passing the value 5.
The first variable is assigned with a.intValue(). The value of a is 5 so value of first will be 5.
The second variable is assigned directly to a. Due to unboxing, the compiler internally assigns the
integer value of a that is 5 to second.
OOP-CBS-Unit 3

JUnit

In a typical, test-driven development (TDD) approach, developers focus on unit testing


every chunk of the code they develop. The better the testing of a product, the better is the
quality of it. We all know, that testing should go parallelly with each passing phase of the
software development life cycle.

Starting from requirement and analysis to design & development till maintenance, every
phase should have an appropriate testing phase associated with it. Unit testing after
development is what is advisable to build a robust application and to have an optimized
code in place.

What Is Unit Testing?

Unit testing is testing of a small logic or a code to verify that the output of the code is as
expected on the input of a specific data and/or on satisfying certain condition(s). Usually,
the unit tests are supposed to be independent of the other tests.

Unit tests are not feasible to test complex interfaces with another application or third
party/external services. A unit test targets only a small unit of code that could be just a
method or a class.

It helps the developer discover issues in the current logic and any regression failures due to
the current change. Besides, it also provides insight into how the current code could impact
future implementation.
Test Coverage

The percentage of code that is tested by unit tests is called test coverage.

The objective is to have better and more test coverage of the code which in future continues
to add up to the regression test suite and helps to increase automated test execution and
verification, thereby, reducing the manual effort involved in regression testing.

Running tests automatically helps to identify software regression issues introduced by


changes in the current code. Having a high-test coverage of your code allows you to
continue developing features without having to perform a lot of manual tests.

Many come with a question as to how much test coverage is essential. The answer to this
question is that there is no hard and fast rule to how much coverage of tests is essential; it
is all judgemental. The judgment gets better with experience on the application workflow
and historic knowledge of the defects found so far.

Efficient tests need not necessarily mean having 100% test coverage or incorporating
automation tests and/or unit tests for every single branch or path coverage.

Certain trivial verifications like a validation error message for a mandatory field left blank
that hasn’t flawed since years need not be included in the regression suite.

Manual Testing Vs Automated Testing


Unit Testing can be done via two approaches:

1. Manual testing
2. Automated testing

In both the approaches the workflow remains common:

1. Creating a test case


2. Reviewing it
3. Rework if corrections needed
4. Execute the test case
5. Analyze the test results

Automated Testing is preferred over Manual Testing for the below reasons:

Manual Testing Automated testing

When a testcase is executed manually When a testcase is executed with the help
without an intervention of a tool is called of a tool without much manual intervention
manual testing. is called automated testing.

Repetitive manual efforts are included. Repetitive manual efforts may be avoided.

Human efforts in manual testing could be Automation tests are faster and error free
erroneous and time consuming. compared to the manual efforts.
Testing resources required are more for Less testers are needed to execute
running every testcase manually thereby, automated tests using the designated
adding to the investment in the resources. automated tool(s) hence there is less
investment in testing resources thus
adding to the profitability.

Manual testing has to be limited to a small Many different test scenarios can be
test coverage considering the timeline automated and can be executed multiple
restrictions. Hence, there is a risk of times even under time and resource crisis
skipping many test scenarios thus leading hence leading to better test coverage and
to risk of defect leakage as well. better quality of the deliverable.

Unit Test Framework

We may have the next question as to what does a typical automation unit test case looks
like and the framework it follows. The developers use the Unit Test framework for
creating automated unit test cases.

1. In order to verify if the code is logically working as expected, a testcase with a


specific checkpoint or verification criterion is created.
2. When the testcase is executed, either the criteria/condition passes or fails.
3. A log is generated as per the testcase workflow.
4. The framework will report a summarized result on the passed test cases and
failed ones.
5. Per the severity of the failure, the testcase may not proceed further and may
stop subsequent execution.
6. There could be certain low severe failures that get reported in the log
however it doesn’t show a hard stop but continues without blocking the
further test steps.

What Is JUnit?
JUnit is an open-source framework that is used for writing and executing unit tests in Java
programming language. It is one of the best-known unit testing frameworks.

The below image shows the different well-known automation unit testing tools.

Enlisted below are the attributes that JUnit is packaged with:

● There is a humongous list of Annotations to identify, execute, and support


many features for the test methods.
● There are Assertions for verifying the expected results.
● It provides Test Runner for executing the tests.
● JUnit provides a basic built-in template so that you may write small, simple
test cases in no time.
● JUnit tests help you to write independent modules, thereby bettering the
coverage of the test and the quality of the application.
● It not only allows easy creation and execution of tests but also presents the
developer with a clean and clear explicit report that eliminates the need for
the developer to search through the path of the reports and test results.
● Until the test execution is sailing through smoothly, you may relax watching at
the green-colored test progress bar that shows while execution is in progress
whereas it alerts you in ‘red’ as soon as the test fails a verification checkpoint.
● Test suites can be created in order to put a sequence or related set of test
cases together.
Examples Of JUnit Testcase

Given below are the two examples of a very basic Hello World program to get an
understanding of how a JUnit test class looks like or how different does it look when
compared with a usual Java class file.

Example #1:

Here is a JUnit testcase HelloWorldJUnit.java that verifies that the string “Hello world”
matches the string “hello world” which fails on execution, as the match is case sensitive.
Hence, the two strings don’t match and the test fails.

The code for HelloWorldJUnit.java

package demo.tests;
import static org.junit.Assert.*;
import org.junit.Test;
public class HelloWorldJUnit {
@Test
public void test() {
assertEquals("Hello world","hello world");
}
}
Example #2:

Here, we will see how a usual Java class file interacts with a JUnit testcase. We create a
Java class file HelloWorld_Java.java with a constructor that allows us to pass a String value
and a method getText() to fetch the string value.

JUnit Test class HelloWorldJUnit.java is created such that the class object for
HelloWorld_Java is created and the actual string value is passed to the object. The
assertEquals() from JUnit verifies if the expected and actual string values match.

The code for HelloWorld_Java.java


package demo.tests;
import static org.junit.Assert.*;
import org.junit.Test;
public class HelloWorldJUnit {
@Test
public void test() {
assertEquals("Hello world","hello world");
}
}
The code for HelloWorldJUnit.java

package demo.tests;
public class HelloWorldJUnit{
private String s;
public HelloWorld_Java(String s)
{
@Test
public void test() {
HelloWorld_Java hw=new HelloWorld_Java("Hello World");
assertEquals(hw.getText(),"Hello World");
}
}
The resultant looks like below where we see the two strings match. Hence, JUnit test is
passed.
OOP - Unit-3 - Assignment

Level-1
Q:
Write a Java program which handles Push operation and Pop operation on stack
concurrently.

Level-2
Q:
Write a Java program which first generates a set of random numbers and then
determines negative, positive even, positive odd numbers concurrently.

Level-3
Q:

Simulate the Math Server using Multithreading.


DEPARTMENT OF COMPUTER SCIENCE & ENGINEERING

Branch : CSE
Sub Code : CS3391 Year/Sem: II/III
Sub Name : Object Oriented Programming Common to:CSBS

Part A
Sl.no Questions Blooms
CO
Level*
1 CO3
Sketch the exception class hierarchy B3

2 CO3
Write a program to read multiple Integer values from a B3

single line of input in Java.

3 CO3
Enumerate the difference between throw and throws
B1
keyboard
4 CO3
Define uncaught exceptions. B1

5 CO3
List the advantages of using exception handling. B1

6 CO3
Justify the purpose of the finally clause of a B5
try-catch-finally statement.
7 CO3 B3
Sketch the different states in thread.

8 List the advantages of Multitasking. CO3 B1


9 CO3 B1
List the importance of thread constructor.
10 CO3 B1
Define daemon thread and identify the method which is
used to create the daemon thread.
11 CO3 B2
Contrast Multithreading and Multitasking

12 CO3 B1
List the methods used for inter thread communication.

13 CO3 B1
Enumerate the difference between yielding and sleeping of
threads with an example.

Part B
Sl.no Blooms
CO
Questions Level*

1 CO3 B5
Summarize the following with example program

i.Arithmetic exception

ii.Arrayoutofbound exception
2 CO3 B2
Describe in detail about multi thread programming with

examples.
3 CO3 B3
Write a Java Program to explain the concept of User
Defined Exception.
4 CO3 B4
Explain the different types of exceptions and the exception
hierarchy in java with appropriate examples.
5 Explain inter thread communication in Java. CO3 B4
6 Create two threads and assign names ‘Scooby’ and CO3 B6

‘Shaggy’ to the two threads. Display both thread names.

7 Illustrate Producer Consumer Problem using CO3 B4

Multithreading.

Part C

Sl.no Blooms
CO
Questions Level*

1 CO3 B6
Create a simple real life application program in java
to illustrate the use of Multithreading.
2 CO3 B4
Illustrate the concept of Synchronization in Java
using the method static synchronization.
3 CO3 B6
Develop a Java Program to create a deadlock
between two threads.
Multithreading - MCQ

What is true about threads?

a.Threads consumes CPU in best possible manner


b.Threads enables multi processing.
c.Multi threading reduces idle time of CPU
d.All

A thread can acquire a lock by using which reserved keyword?

a.volatile
b.synchronized
c.locked
d.none

How many threads can a process contain?

a.1
b.2
c.multiple
d.none

What is sometimes also called a lightweight process?

a.Thread
b.Process
c.JVM
d.

What are valid points about thread

a.Thread are subdivision of Process.


b.One or more Threads runs in the context of process.
c.Threads can execute any part of process. And same part of process can be executed by
multiple Threads.
d.All
What are valid point about processes

a.Processes have their own copy of the data segment of the parent process
b.Threads have direct access to the data segment of its process
c.Processes have their own address
d.All of these

Which is thread safe?

a.StringBuffer
b.StringBuilder
c.All
d.None

How can we create Thread

a.By Extending Thread class


b.Implementing Runnable interface
c.By using Executor framework - which can internally form threads
d.All

Which of these is not a Thread state?

a.New
b.Runnable
c.sleep
d.terminated

Synchronized instance methods acquire lock on?

a.object
b.class
c.All
d.None
What state does Thread enter in when it has been created and started?

a.New
b.Runnable
c.Running
d.Waiting

Which method can be used to find whether Thread hasn't entered dead state?

a.isAlive()
b.isRunning()
c.isNotDead
d.All

What is valid about threads

a.Threads have their own heap allocated area.


b.Threads have their own stack.
c.Threads doesn't have own stack.
d.None

How can you ensure all threads that started from main must end in order in which they
started and also main should end in last

a.join() method
b.sleep() method
c.wait() method
d.run() method

Which of these is valid about threads in java

a.Thread behaviour is unpredictable


b.execution of Threads depends on Thread scheduler
c.Same threading program may produce different output in subsequent executions even on
same platform
d.All
Which method restarts the thread

a.start()
b.restart()
c.restartThread()
d.none

What is true about acquiring object lock before calling wait(), notify() and notifyAll()?

a.it’s mandatory to acquire object lock before calling wait(), notify() and notifyAll()
methods on object
b.If we call wait(), notify() and notifyAll() methods without acquiring object lock i.e. from
outside synchronize block then java.lang.IllegalMonitorStateException is thrown at
runtime.
c.wait(), notify() and notifyAll() methods are always called from Synchronized block only
d.all

What is difference between starting thread with run() and start() method?

a.There is no difference
b.When you call start() method, main thread internally calls run() method to start newly
created Thread
c.run() calls start() method internally
d.None

What are valid statements for suspend() and resume() method?

a.Suspend() method is deadlock prone.


b.If the target thread holds a lock on object when it is suspended, no thread can lock this
object until the target thread is resumed.
c.If the thread that would resume the target thread attempts to lock this monitor prior to
calling resume, it results in deadlock formation.
d.All

How can Thread go from waiting to runnable state?

a.notify/notifAll
b.When sleep time is up
c.Using resume() method when thread was suspended
d.All
MCQ - Exception Handling

Question 1
The closest common ancestor of RuntimeException, Error, IOException and
ClassNotFoundException is:

Object
Exception
Throwable
Catchable

Question 2
A method that potentially generates a checked exception must include this keyword in its
method signature:

throw
extend
throws
extends

Question 3
Which of the following statements is true about Java's finally block?

The finally block is only executed if an exception is thrown in the try block
The finally block is only executed if an exception is thrown in the catch block
The finally block is only executed if an exception is not thrown in the try or catch block
The finally block is executed regardless of whether an exception is thrown in the try or
catch block

Question 4
If code is structured to handle the IOException before the FileNotFoundException, which of
these results is true?

Both IOException and FileNotFoundException handling routines will run


Only the IOException handling routine will run
Only the FileNotFoundException handling routine will run
The code will not compile
Question 5
To be included within a try-with-resources block, the resource in question must be:

Closeable
Catchable
Runnable
Serializable

Question 6
Which of the following statements is true about exception handling in Java:

A try block can have many catch blocks but only one finally block
A try block can have many catch blocks and many finally blocks
A try block must have one finally block for each catch block
A try block must have at least one catch block to have a finally block

Question 7
A JVM level problem that terminates the current runtime is a subtype of:

RuntimeException
Exception
FatalException
Error

Question 8
All unchecked exceptions extend which class at some point in their ancestry?

RuntimeException
Exception
FatalException
Error

Question 9
Which keyword raises an exception in Java code?

try
throw
break
throws
Question 10
Exceptions thrown in a try-with-resources block, after an exception has already been
thrown in the try block, are accessible as:

ResourceExceptions
HiddenException
CloseableExceptions
SuppressedExceptions
Java Threads
A thread is a thread of execution in a program. The Java Virtual Machine allows an application to have multiple threads of execution
running concurrently. This hands-on lab takes you through the basics of using Java threading.

Resources

Threads section of Java tutorial


Thread dump analyzer 2.0 from java.net

Exercises

Exercise 1: Extending Thread class


Exercise 2: Implementing Runnable interface
Exercise 3: ThreadGroup, ThreadPriority, View all threads
Exercise 4: Synchronization
Exercise 5: Inter-thread communication
Exercise 6: Timer and TimerTask
Homework

Exercise 1: Extending Thread class

In this exercise, you are going to learn how to create and start a thread execution by writing a class that extends Thread class. You will
learn how to start the thread by either not having the start() method in the constructor of the subclass or having it in the constructor of
the subclass.

1. The start() method is NOT in the constructor of the subclass


2. The start() method is in the constructor of the subclass

(1.1) The start() method is NOT in the constructor of the subclass

0. Start NetBeans IDE if you have not done so yet.


1. Create a new NetBeans project

Select File->New Project (Ctrl+Shift+N). The New Project dialog box appears.
Under Choose Project pane, select Java under Categories and Java Application under Projects.
Click Next.

Under Name and Location pane, for the Project Name field, type in ExtendThreadClassTest0 as project name.
For Create Main Class field, type in ExtendThreadClassTest0. (Figure-1.10 below)
Click Finish.

Figure-1.10: Create a new project

Observe that ExtendThreadClassTest0 project appears and IDE generated ExtendThreadClassTest0.java is displayed in the
source editor window of NetBeans IDE.

2. Modify the IDE generated ExtendThreadClassTest0.java as shown in Code-1.11 below. Study the code by paying special attention
to the bold fonted parts. Note that the start() is invoked after the object instance of PrintNameThread class is created.

public class ExtendThreadClassTest0 {


public static void main(String args[]) {

// Create object instance of a class that is subclass of Thread class


System.out.println("Creating PrintNameThread object instance..");
PrintNameThread pnt1 =
new PrintNameThread("A");

// Start the thread by invoking start() method


System.out.println("Calling start() method of " + pnt1.getName() + " thread");
pnt1.start();

}
}
Code-1.11: ExtendThreadClassTest0.java

3. Write PrintNameThread.java as shown in Code-1.12 below.

// Subclass extends Thread class


public class PrintNameThread extends Thread {

PrintNameThread(String name) {
super(name);
}

// Override the run() method of the Thread class.


// This method gets executed when start() method
// is invoked.
public void run() {
System.out.println("run() method of the " + this.getName() + " thread is called" );

for (int i = 0; i < 10; i++) {


System.out.print(this.getName());
}
}
}
Code-1.12: PrintNameThread.java

4. Build and run the project

Right click ExtendThreadClassTest0 project and select Run.


Observe the result in the Output window. (Figure-1.13 below)

Creating PrintNameThread object instance..


Calling start() method of A thread
run() method of the A thread is called
AAAAAAAAAA
Figure-1.13: Result of running ExtendThreadClassTest0 application
5. Modify the ExtendThreadClassTest0.java as shown in Code-1.15 below. The code fragments that need to be added are highlighted
in bold and blue-colored font.

public class ExtendThreadClassTest0 {

public static void main(String args[]) {

// Create object instance of a class that is subclass of Thread class


System.out.println("Creating PrintNameThread object instance..");
PrintNameThread pnt1 =
new PrintNameThread("A");

// Start the thread by invoking start() method


System.out.println("Calling start() method of " + pnt1.getName() + " thread");
pnt1.start();

System.out.println("Creating PrintNameThread object instance..");


PrintNameThread pnt2 =
new PrintNameThread("B");
System.out.println("Calling start() method of " + pnt2.getName() + " thread");
pnt2.start();

System.out.println("Creating PrintNameThread object instance..");


PrintNameThread pnt3 =
new PrintNameThread("C");
System.out.println("Calling start() method of " + pnt3.getName() + " thread");
pnt3.start();
}
}
Code-1.15: Modified ExtendThreadClassTest0.java

6. Build and run the project


Right click ExtendThreadClassTest0 project and select Run.
Observe the result in the Output window. (Figure-1.16 below)

Creating PrintNameThread object instance..


Calling start() method of A thread
Creating PrintNameThread object instance..
Calling start() method of B thread
AAAAAAAAAACreating PrintNameThread object instance..
BCalling start() method of C thread
BBBBBBBBBCCCCCCCCCC
Figure-1.16: Result

7. For your own exercise, modify ExtendThreadClassTest0.java as following. Build and run the application.

Create and start another thread.


Set the name of the thread as "MyOwn"

return to top of the exercise

(1.2) The start() method is in the constructor of the subclass

1. Create a new NetBeans project

Select File->New Project (Ctrl+Shift+N). The New Project dialog box appears.
Under Choose Project pane, select Java under Categories and Java Application under Projects.
Click Next.

Under Name and Location pane, for the Project Name field, type in ExtendThreadClassTest2 as project name.
For Create Main Class field, type in ExtendThreadClassTest2.
Click Finish.

Observe that ExtendThreadClassTest2 project appears and IDE generated ExtendThreadClassTest2.java is displayed in the
source editor window of NetBeans IDE.
2. Modify the IDE generated ExtendThreadClassTest2.java as shown in Code-1.21 below.

public class ExtendThreadClassTest2 {

public static void main(String args[]) {

PrintNameThread pnt1 =
new PrintNameThread("A");

PrintNameThread pnt2 =
new PrintNameThread("B");

PrintNameThread pnt3 =
new PrintNameThread("C");

}
}
Code-1.21: ExtendThreadClassTest2.java

3. Write PrintNameThread.java as shown in Code-1.22 below. Note that the start() method is invoked as part of the constructor
method of the PrintNameThread class.

public class PrintNameThread extends Thread {

PrintNameThread(String name) {
super(name);
// start() method is inside the constructor of the subclass
start();
}

public void run() {


String name = getName();
for (int i = 0; i < 10; i++) {
System.out.print(name);
}
}
}
Code-1.22: PrintNameThread.java

4. Build and run the project

Right click ExtendThreadClassTest2 project and select Run.


Observe the result in the Output window. (Figure-1.23 below)

AAAAAAAAAABBBBBBBBBBCCCCCCCCCC
Figure-1.23: Result of running ExtendThreadClassTest2 application
5. For your own exercise, modify ExtendThreadClassTest2.java as following. Build and run the application.

Create and start another thread.


Set the name of the thread as "MyOwn"

return to top of the exercise

Summary

In this exercise, you have learned how to create and start a thread by extending Thread class.

return to the top

Exercise 2: Implement Runnable interface

In this exercise, you are going to create and start a thread by writing a class that implements Runnable interface.

1. Create and start a thread by implementing Runnable interface - start() method is not in the constructor
2. Create and start a thread by implementing Runnable interface - start() method is in the constructor

(2.1) Create and start a thread by implementing Runnable interface - start() method is not in the constructor

1. Create a new NetBeans project

Select File->New Project (Ctrl+Shift+N). The New Project dialog box appears.
Under Choose Project pane, select Java under Categories and Java Application under Projects.
Click Next.

Under Name and Location pane, for the Project Name field, type in RunnableThreadTest1 as project name.
For Create Main Class field, type in RunnableThreadTest1.
Click Finish.

Observe that RunnableThreadTest1 project appears and IDE generated RunnableThreadTest1.java is displayed in the source
editor window of NetBeans IDE.

2. Modify the IDE generated RunnableThreadTest1.java as shown in Code-2.11 below. Study the code by paying special attention to
the bold fonted parts. Note that the start() method needs to be invoked explicitly after an object instance of the PrintNameRunnable
class is created.

public class RunnableThreadTest1 {

public static void main(String args[]) {

PrintNameRunnable pnt1 = new PrintNameRunnable("A");


Thread t1 = new Thread(pnt1);
t1.start();

PrintNameRunnable pnt2 = new PrintNameRunnable("B");


Thread t2 = new Thread(pnt2);
t2.start();

PrintNameRunnable pnt3 = new PrintNameRunnable("C");


Thread t3 = new Thread(pnt3);
t3.start();

}
}
Code-2.11: RunnableThreadTest1.java

3. Write PrintNameRunnable.java as shown in Code-2.12 below.

// The class 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);
}
}
}
Code-2.12: PrintNameRunnable.java

4. Build and run the project

Right click RunnableThreadTest1 project and select Run.


Observe the result in the Output window. (Figure-2.13 below)

ACBACBACBACBACABCABCABCABCABCB
Figure-2.13: Result of running RunnableThreadTest1 application

5. For your own exercise, do the following. Build and run the application.

Create another class called MyOwnRunnableClass that implements Runnable interface


MyOwnRunnableClass displays values 1 to 10 inside its run() method
Modify RunnableThreadTest1.java to start 2 thread instances of MyOwnRunnableClass.

return to top of the exercise

(2.2) Create and start a thread by implementing Runnable interface - start() method is in the constructor

1. Create a new NetBeans project

Select File->New Project (Ctrl+Shift+N). The New Project dialog box appears.
Under Choose Project pane, select Java under Categories and Java Application under Projects.
Click Next.

Under Name and Location pane, for the Project Name field, type in RunnableThreadTest2 as project name.
For Create Main Class field, type in RunnableThreadTest2.
Click Finish.

Observe that RunnableThreadTest2 project appears and IDE generated RunnableThreadTest2.java is displayed in the source
editor window of NetBeans IDE.
2. Modify the IDE generated RunnableThreadTest2.java as shown in Code-2.21 below. Study the code by paying special attention to
the bold fonted parts.

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");
}
}
Code-2.21: RunnableThreadTest2.java

3. Write PrintNameRunnable.java as shown in Code-2.22 below. Study the code by paying special attention to the bold fonted parts.
Note that the start() method is in the constructor of the PrintNameRunnable class.

// The class 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);
}
}
}
Code-2.22: PrintNameRunnable.java

4. Build and run the project

Right click RunnableThreadTest2 project and select Run.


Observe the result in the Output window. (Figure-1.23 below)

ABCABCABCABCABCABCABCBACBACBAC
Figure-2.23: Result of running RunnableThreadTest2 application

return to top of the exercise

Summary

In this exercise, you have learned how to create a class that implements Runnable interface and starts a thread.

return to the top

Exercise 3: ThreadsGroup, View all threads, ThreadPriority

In this exercise, you are going to learn how to display information on a ThreadGroup, how to set a thread priority, and so on.

1. Display threads of a ThreadGroup


2. Display all threads in the system
3. Set thread priority

(3.1) Display threads of a ThreadGroup

1. Create a new NetBeans project

Select File->New Project (Ctrl+Shift+N). The New Project dialog box appears.
Under Choose Project pane, select Java under Categories and Java Application under Projects.
Click Next.

Under Name and Location pane, for the Project Name field, type in ThreadGroupTest as project name.
For Create Main Class field, type in ThreadGroupTest.
Click Finish.

Observe that ThreadGroupTest project appears and IDE generated ThreadGroupTest.java is displayed in the source editor
window of NetBeans IDE.
2. Modify the IDE generated ThreadGroupTest.java as shown in Code-3.11 below. Study the code by paying special attention to the
bold fonted parts.

public class ThreadGroupTest {

public static void main (String[] args) {

// Start three threads first. They should belong


// to a same ThreadsGroup.
new SimpleThread("Boston").start();
new SimpleThread("New York").start();
new SimpleThread("Seoul").start();

// Get ThreadGroup of the current thread and display


// the number of active threads that belong to the
// ThreadGroup.
ThreadGroup group = Thread.currentThread().getThreadGroup();
System.out.println("Number of active threads in this thread group = "
+ group.activeCount());

// Display the names of the threads in the current


// ThreadGroup.
Thread[] tarray = new Thread[10];
int actualSize = group.enumerate(tarray);
for (int i=0; i<actualSize;i++){
System.out.println("Thread " + tarray[i].getName()
+ " in thread group " + group.getName());
}

}
}
Code-3.11: ThreadGroupTest.java

3. Write SimpleThread.java as shown in Code-3.12 below.

public class SimpleThread extends Thread {

public SimpleThread(String str) {


super(str);
}

public void run() {


for (int i = 0; i < 5; i++) {
// System.out.format("%d %s%n", i, getName());
try {
sleep((long)(Math.random() * 1000));
} catch (InterruptedException e) {}
}
System.out.format("DONE! %s%n", getName());
}
}
Code-3.12: SimpleThread.java

4. Build and run the project

Right click ThreadGroupTest project and select Run.


Observe the result in the Output window. (Figure-3.13 below)

Number of active threads in this thread group = 4


Thread main in thread group main
Thread Boston in thread group main
Thread New York in thread group main
Thread Seoul in thread group main
DONE! Seoul
DONE! New York
DONE! Boston
Figure-3.13: Result of running ThreadGroupTest application

return to top of the exercise

5. For your own exercise, do the following. Build and run the application.

Modify ThreadGroupTest.java to create another (4th) SimpleThread instance using your capital city of your country.

(3.2) Display all threads in the system

1. Create a new NetBeans project

Select File->New Project (Ctrl+Shift+N). The New Project dialog box appears.
Under Choose Project pane, select Java under Categories and Java Application under Projects.
Click Next.

Under Name and Location pane, for the Project Name field, type in DisplayAllThreads as project name.
For Create Main Class field, type in DisplayAllThreads.
Click Finish.

Observe that DisplayAllThreads project appears and IDE generated DisplayAllThreads.java is displayed in the source editor
window of NetBeans IDE.

2. Modify the IDE generated DisplayAllThreads.java as shown in Code-3.21 below. Study the code by paying special attention to the
bold fonted parts.

public class DisplayAllThreads {

public static void main(String[] args) {

// Start three threads first. They should belong


// to a same ThreadsGroup.
new SimpleThread("Boston").start();
new SimpleThread("New York").start();
new SimpleThread("Seoul").start();

Thread[] tarray = findAllThreads();

for (int i=0; i<tarray.length;i++){


System.out.println("Thread " + tarray[i].getName()
+ " in thread group " + tarray[i].getThreadGroup().getName());
}

// Create an array of all threads in the system.


public static Thread[] findAllThreads() {
ThreadGroup group = Thread.currentThread().getThreadGroup();

ThreadGroup topGroup = group;

while (group != null) {


topGroup = group;
group = group.getParent();
}

int estimatedSize = topGroup.activeCount() * 2;


Thread[] slackList = new Thread[estimatedSize];

int actualSize = topGroup.enumerate(slackList);

Thread[] list = new Thread[actualSize];


System.arraycopy(slackList, 0, list, 0, actualSize);

return list;
}
}
Code-3.21: DisplayAllThreads.java

3. Write SimpleThread.java as shown in Code-3.22 below.

public class SimpleThread extends Thread {

public SimpleThread(String str) {


super(str);
}

public void run() {


for (int i = 0; i < 5; i++) {
// System.out.format("%d %s%n", i, getName());
try {
sleep((long)(Math.random() * 1000));
} catch (InterruptedException e) {}
}
System.out.format("DONE! %s%n", getName());
}
}
Code-3.22: SimpleThread.java

4. Build and run the project

Right click DisplayAllThreads project and select Run.


Observe the result in the Output window. (Figure-3.23 below)

Thread Reference Handler in thread group system


Thread Finalizer in thread group system
Thread Signal Dispatcher in thread group system
Thread main in thread group main
Thread Boston in thread group main
Thread New York in thread group main
Thread Seoul in thread group main
DONE! New York
DONE! Seoul
DONE! Boston
Figure-1.23: Result of running DisplayAllThreads application

5. For your own exercise, do the following. Build and run the application.

Modify DisplayAllThreads.java to create another (4th) SimpleThread instance using your capital city of your country.

return to top of the exercise

(3.3) Set thread priority

1. Create a new NetBeans project

Select File->New Project (Ctrl+Shift+N). The New Project dialog box appears.
Under Choose Project pane, select Java under Categories and Java Application under Projects.
Click Next.

Under Name and Location pane, for the Project Name field, type in ThreadsPriority as project name.
For Create Main Class field, type in ThreadsPriority.
Click Finish.

Observe that ThreadsPriority project appears and IDE generated ThreadsPriority.java is displayed in the source editor window
of NetBeans IDE.

2. Modify the IDE generated ThreadsPriority.java as shown in Code-3.31 below. Study the code by paying special attention to the
bold fonted parts.

public class ThreadsPriority {

public static void main(String[] args) {

Thread t1 = new SimpleThread("Boston");


t1.start();
// Set the thread priority to 10(highest)
t1.setPriority(10);

Thread t2 = new SimpleThread("New York");


t2.start();
// Set the thread priority to 5
t2.setPriority(5);

Thread t3 = new SimpleThread("Seoul");


t3.start();
// Set the thread priority to 1
t3.setPriority(1);

}
}
Code-3.31: ThreadsPriority.java

3. Write SimpleThread.java as shown in Code-3.32 below.

public class SimpleThread extends Thread {

public SimpleThread(String str) {


super(str);
}

public void run() {


for (int i = 0; i < 10; i++) {
System.out.println(i + " " + getName()
+ " Priority = " + getPriority());
}
System.out.println("Done! " + getName());
}
}
Code-3.32: SimpleThread.java

4. Build and run the project

Right click ThreadsPriority project and select Run.


Observe the result in the Output window. (Figure-3.33 below)

0 Boston Priority = 10
0 Seoul Priority = 1
0 New York Priority = 5
1 Boston Priority = 10
1 Seoul Priority = 1
1 New York Priority = 5
2 Boston Priority = 10
2 Seoul Priority = 1
3 Boston Priority = 10
2 New York Priority = 5
4 Boston Priority = 10
3 New York Priority = 5
5 Boston Priority = 10
6 Boston Priority = 10
7 Boston Priority = 10
8 Boston Priority = 10
9 Boston Priority = 10
Done! Boston
4 New York Priority = 5
5 New York Priority = 5
6 New York Priority = 5
7 New York Priority = 5
8 New York Priority = 5
9 New York Priority = 5
Done! New York
3 Seoul Priority = 1
4 Seoul Priority = 1
5 Seoul Priority = 1
6 Seoul Priority = 1
7 Seoul Priority = 1
8 Seoul Priority = 1
9 Seoul Priority = 1
Done! Seoul
Figure-3.33: Result of running ThreadsPriority application

return to top of the exercise

Summary

In this exercise, you have learned how to retrieve information on a ThreadGroup.

return to the top

Exercise 4: Synchronization

In this exercise, you are going to exercise how to do synchronization among threads.

1. Build and run a program in which threads are NOT synchronized


2. Build an run a program in which threads are synchronized through synchronized method
3. Build and run a program in which threads are synchronized through synchronized statement on a common object

(4.1) Build and run a program in which threads are NOT synchronized

In this step, you are going to build an application that displays a result that is not desirable since threads are not synchronized.

1. Create a new NetBeans project

Select File->New Project (Ctrl+Shift+N). The New Project dialog box appears.
Under Choose Project pane, select Java under Categories and Java Application under Projects.
Click Next.

Under Name and Location pane, for the Project Name field, type in UnsynchronizedExample as project name.
For Create Main Class field, type in UnsynchronizedExample.
Click Finish.

Observe that UnsynchronizedExample project appears and IDE generated UnsynchronizedExample.java is displayed in the
source editor window of NetBeans IDE.

2. Modify the IDE generated UnsynchronizedExample.java as shown in Code-4.11 below.

public class UnsynchronizedExample {

public static void main(String[] args) {


new PrintStringsThread("Hello ", "there.");
new PrintStringsThread("How are ", "you?");
new PrintStringsThread("Thank you ", "very much!");
}

}
Code-4.11: UnsynchronizedExample.java

3. Write PrintStringsThread.java as shown in Code-4.12 below.

public class PrintStringsThread implements Runnable {

Thread thread;
String str1, str2;
PrintStringsThread(String str1, String str2) {
this.str1 = str1;
this.str2 = str2;
thread = new Thread(this);
thread.start();
}

public void run() {


TwoStrings.print(str1, str2);
}

}
Code-4.12: PrintStringsThread.java

4. Write TwoStrings.java as shown in Code-4.13 below. Study the code by paying special attention to the bold fonted parts. Note that
the print method is not synchronized.

public class TwoStrings {

// This method is not synchronized


static void print(String str1, String str2) {
System.out.print(str1);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
System.out.println(str2);
}
}
Code-4.13: TwoStrings.java

5. Build and run the project

Right click UnsynchronizedExample project and select Run.


Observe the result in the Output window. (Figure-4.14 below)

Hello How are Thank you there.


very much!
you?
Figure-4.14: Result of running UnsynchronizedExample application

return to top of the exercise

(4.2) Build and run a program in which threads are synchronized through synchronized method

In this step, you are going to build an application that displays a desired result because the threads are synchronized.

1. Create a new NetBeans project

Select File->New Project (Ctrl+Shift+N). The New Project dialog box appears.
Under Choose Project pane, select Java under Categories and Java Application under Projects.
Click Next.

Under Name and Location pane, for the Project Name field, type in SynchronizedExample1 as project name.
For Create Main Class field, type in SynchronizedExample1.
Click Finish.

Observe that SynchronizedExample1 project appears and IDE generated SynchronizedExample1.java is displayed in the
source editor window of NetBeans IDE.

2. Modify the IDE generated SynchronizedExample1.java as shown in Code-4.21 below.

public class SynchronizedExample1 {

public static void main(String[] args) {


new PrintStringsThread("Hello ", "there.");
new PrintStringsThread("How are ", "you?");
new PrintStringsThread("Thank you ", "very much!");
}

}
Code-4.21: SynchronizedExample1.java

3. Write PrintStringsThread.java as shown in Code-4.22 below.

public class PrintStringsThread implements Runnable {

Thread thread;
String str1, str2;

PrintStringsThread(String str1, String str2) {


this.str1 = str1;
this.str2 = str2;
thread = new Thread(this);
thread.start();
}

public void run() {


TwoStrings.print(str1, str2);
}

}
Code-4.22: PrintStringsThread.java

4. Write TwoStrings.java as shown in Code-4.23 below. Study the code by paying special attention to the bold fonted parts.

public class TwoStrings {

// This method is now synchronized


synchronized static void print(String str1, String str2) {
System.out.print(str1);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
System.out.println(str2);
}
}
Code-4.23: TwoStrings.java

5. Build and run the project

Right click SynchronizedExample1 project and select Run.


Observe the result in the Output window. (Figure-4.24 below)

How are you?


Thank you very much!
Hello there.
Figure-4.24: Result of running UnSynchronizedExample1 application

return to top of the exercise

(4.3) Build and run a program in which threads are synchronized through synchronized statement on common object

In this step, you are going to build another application that displays a desired result because the threads are synchronized.

1. Create a new NetBeans project

Select File->New Project (Ctrl+Shift+N). The New Project dialog box appears.
Under Choose Project pane, select Java under Categories and Java Application under Projects.
Click Next.

Under Name and Location pane, for the Project Name field, type in SynchronizedExample2 as project name.
For Create Main Class field, type in SynchronizedExample2.
Click Finish.

Observe that SynchronizedExample2 project appears and IDE generated SynchronizedExample2.java is displayed in the
source editor window of NetBeans IDE.

2. Modify the IDE generated SynchronizedExample2.java as shown in Code-4.31 below.

public class SynchronizedExample2 {

public static void main(String[] args) {

TwoStrings ts = new TwoStrings();

new PrintStringsThread("Hello ", "there.", ts);


new PrintStringsThread("How are ", "you?", ts);
new PrintStringsThread("Thank you ", "very much!", ts);
}

}
Code-4.31: SynchronizedExample2.java

3. Write PrintStringsThread.java as shown in Code-4.32 below. Study the code by paying special attention to the bold fonted parts.

public class PrintStringsThread implements Runnable {

Thread thread;
String str1, str2;
TwoStrings ts;

PrintStringsThread(String str1, String str2,


TwoStrings ts) {
this.str1 = str1;
this.str2 = str2;
this.ts = ts;
thread = new Thread(this);
thread.start();
}

public void run() {


// Synchronize over TwoString object
synchronized (ts) {
ts.print(str1, str2);
}
}
}
Code-4.32: PrintStringsThread.java

4. Write TwoStrings.java as shown in Code-4.33 below.

public class TwoStrings {

static void print(String str1, String str2) {


System.out.print(str1);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
System.out.println(str2);
}
}
Code-4.33: TwoStrings.java

5. Build and run the project

Right click SynchronizedExample2 project and select Run.


Observe the result in the Output window. (Figure-4.34 below)

How are you?


Thank you very much!
Hello there.
Figure-4.34: Result of running UnSynchronizedExample2 application

return to top of the exercise


Summary

In this exercise, you have learned how to use synchronization.

return to the top

Exercise 5: Inter-thread communication


1. Producer-Consumer without inter-thread communication
2. Producer-Consumer with inter-thread communication

(5.1) Producer-Consumer without inter-thread communication

1. Create a new NetBeans project

Select File->New Project (Ctrl+Shift+N). The New Project dialog box appears.
Under Choose Project pane, select Java under Categories and Java Application under Projects.
Click Next.

Under Name and Location pane, for the Project Name field, type in ProducerConsumerUnsynchronized as project name.
For Create Main Class field, type in ProducerConsumerUnsynchronized.
Click Finish.

Observe that ProducerConsumerUnsynchronized project appears and IDE generated


ProducerConsumerUnsynchronized.java is displayed in the source editor window of NetBeans IDE.

2. Modify the IDE generated ProducerConsumerUnsynchronized.java as shown in Code-5.11 below.

public class ProducerConsumerUnsynchronized {

public static void main(String[] args) {

CubbyHole c = new CubbyHole();

Producer p1 = new Producer(c, 1);


Consumer c1 = new Consumer(c, 1);

p1.start();
c1.start();
}
}
Code-5.11: ProducerConsumerUnsynchronized.java

3. Write CubbyHole.java as shown in Code-5.12 below. Study the code by paying special attention to the bold fonted parts.

// Unsynchronized CubbyHole.
//
// Results are unpredictable; a number may be read before a number has
// been produced or multiple numbers may be produced with only one or
// two being read adding synchronization ensures that a number is first
// produced, then read in the correct order.

public class CubbyHole {


private int contents;
private boolean available = false;

public int get() {


available = false;
return contents;
}

public void put(int value) {


contents = value;
available = true;
}
}
Code-5.12: CubbyHole.java

4. Write Producer.java as shown in Code-5.13 below.

public class Producer extends Thread {


private CubbyHole cubbyhole;
private int number;

public Producer(CubbyHole c, int number) {


cubbyhole = c;
this.number = number;
}

public void run() {


for (int i = 0; i < 10; i++) {
cubbyhole.put(i);
System.out.println("Producer #" + this.number
+ " put: " + i);
try {
sleep((int)(Math.random() * 100));
} catch (InterruptedException e) { }
}
}
}
Code-5.13: Producer.java

5. Write Consumer.java as shown in Code-5.14 below.

public class Consumer extends Thread {


private CubbyHole cubbyhole;
private int number;

public Consumer(CubbyHole c, int number) {


cubbyhole = c;
this.number = number;
}

public void run() {


int value = 0;
for (int i = 0; i < 10; i++) {
value = cubbyhole.get();
System.out.println("Consumer #" + this.number
+ " got: " + value);
}
}
}
Code-5.14: Consumer.java

6. Build and run the project

Right click ProducerConsumerUnsynchronized project and select Run.


Observe the result in the Output window. (Figure-5.15 below)

Producer #1 put: 0
Consumer #1 got: 0
Consumer #1 got: 0
Consumer #1 got: 0
Consumer #1 got: 0
Consumer #1 got: 0
Consumer #1 got: 0
Consumer #1 got: 0
Consumer #1 got: 0
Consumer #1 got: 0
Consumer #1 got: 0
Producer #1 put: 1
Producer #1 put: 2
Producer #1 put: 3
Producer #1 put: 4
Producer #1 put: 5
Producer #1 put: 6
Producer #1 put: 7
Producer #1 put: 8
Producer #1 put: 9
Figure-5.15: Result of running ProducerConsumerUnsynchronized application

return to top of the exercise

(5.2) Producer-Consumer with inter-thread communication

1. Create a new NetBeans project

Select File->New Project (Ctrl+Shift+N). The New Project dialog box appears.
Under Choose Project pane, select Java under Categories and Java Application under Projects.
Click Next.

Under Name and Location pane, for the Project Name field, type in ProducerConsumerSynchronized as project name.
For Create Main Class field, type in ProducerConsumerSynchronized.
Click Finish.

Observe that ProducerConsumerSynchronized project appears and IDE generated ProducerConsumerSynchronized.java is


displayed in the source editor window of NetBeans IDE.

2. Modify the IDE generated ProducerConsumerSynchronized.java as shown in Code-5.21 below.

public class ProducerConsumerSynchronized {

public static void main(String[] args) {

CubbyHole c = new CubbyHole();

Producer p1 = new Producer(c, 1);


Consumer c1 = new Consumer(c, 1);

p1.start();
c1.start();
}
}
Code-5.21: ProducerConsumerSynchronized.java

3. Write CubbyHole.java as shown in Code-5.22 below. Study the code by paying special attention to the bold fonted parts.

public class CubbyHole {

private int contents;


private boolean available = false;

public synchronized int get(int who) {


while (available == false) {
try {
wait();
} catch (InterruptedException e) { }
}
available = false;
System.out.format("Consumer %d got: %d%n", who, contents);
notifyAll();
return contents;
}

public synchronized void put(int who, int value) {


while (available == true) {
try {
wait();
} catch (InterruptedException e) { }
}
contents = value;
available = true;
System.out.format("Producer %d put: %d%n", who, contents);
notifyAll();
}
}
Code-5.22: CubbyHole.java
4. Write Producer.java as shown in Code-5.23 below.

public class Producer extends Thread {

private CubbyHole cubbyhole;


private int number;

public Producer(CubbyHole c, int number) {


cubbyhole = c;
this.number = number;
}

public void run() {


for (int i = 0; i < 10; i++) {
cubbyhole.put(number, i);
try {
sleep((int)(Math.random() * 100));
} catch (InterruptedException e) { }
}
}
}
Code-5.23: Producer.java

5. Write Consumer.java as shown in Code-5.24 below.

public class Consumer extends Thread {


private CubbyHole cubbyhole;
private int number;

public Consumer(CubbyHole c, int number) {


cubbyhole = c;
this.number = number;
}

public void run() {


int value = 0;
for (int i = 0; i < 10; i++) {
value = cubbyhole.get(number);
}
}
}
Code-5.24: Consumer.java

6. Build and run the project

Right click ProducerConsumerSynchronized project and select Run.


Observe the result in the Output window. (Figure-5.25 below)

Producer 1 put: 0
Consumer 1 got: 0
Producer 1 put: 1
Consumer 1 got: 1
Producer 1 put: 2
Consumer 1 got: 2
Producer 1 put: 3
Consumer 1 got: 3
Producer 1 put: 4
Consumer 1 got: 4
Producer 1 put: 5
Consumer 1 got: 5
Producer 1 put: 6
Consumer 1 got: 6
Producer 1 put: 7
Consumer 1 got: 7
Producer 1 put: 8
Consumer 1 got: 8
Producer 1 put: 9
Consumer 1 got: 9
Figure-5.25: Result of running ProducerConsumerSynchronized application

return to top of the exercise

Summary

In this exercise, you have learned how to perform inter-thread commmunication by the usage of wait(), notify(), and notifyAll()
methods.

return to the top

Exercise 6: Timer and TimerTask


In this exercise, you will learn how to use Timer and TimerTask to schedule a single or repeating task.

1. Schedule one-time task


2. Schedule repeating task

(6.1) Schedule one-time task

1. Create a new NetBeans project

Select File->New Project (Ctrl+Shift+N). The New Project dialog box appears.
Under Choose Project pane, select Java under Categories and Java Application under Projects.
Click Next.

Under Name and Location pane, for the Project Name field, type in TimerReminder as project name.
For Create Main Class field, type in TimerReminder.
Click Finish.

Observe that TimerReminder project appears and IDE generated TimerReminder.java is displayed in the source editor window
of NetBeans IDE.

2. Modify the IDE generated TimerReminder.java as shown in Code-6.11 below. Study the code by paying special attention to the
bold fonted parts.

import java.util.Timer;
import java.util.TimerTask;

/**
* Simple demo that uses java.util.Timer to schedule a task to execute
* once 5 seconds have passed.
*/

public class TimerReminder {

Timer timer;

public TimerReminder(int seconds) {


timer = new Timer();
timer.schedule(new RemindTask(), seconds*1000);
}

class RemindTask extends TimerTask {


public void run() {
System.out.println("Time's up!");
timer.cancel(); //Terminate the timer thread
}
}

public static void main(String args[]) {


System.out.println("About to schedule Reminder task in 5 seconds");
new TimerReminder(5);
System.out.println("Task scheduled.");
}
}
Code-6.11: TimerReminder.java

3. Build and run the project

Right click TimerReminder project and select Run.


Observe the result in the Output window. (Figure-6.12 below)

About to schedule Reminder task in 5 seconds


Task scheduled.
Time's up!
Figure-6.12: Result of running UnTimerReminder application

return to top of the exercise

(6.2) Schedule a repeating task

1. Create a new NetBeans project

Select File->New Project (Ctrl+Shift+N). The New Project dialog box appears.
Under Choose Project pane, select Java under Categories and Java Application under Projects. Click Next.
Under Name and Location pane, for the Project Name field, type in AnnoyingBeep as project name.
For Create Main Class field, type in AnnoyingBeep.
Click Finish.

Observe that AnnoyingBeep project appears and IDE generated AnnoyingBeep.java is displayed in the source editor window of
NetBeans IDE.

2. Modify the IDE generated AnnoyingBeep.java as shown in Code-6.21 below. Study the code by paying special attention to the bold
fonted parts.

import java.util.Timer;
import java.util.TimerTask;
import java.awt.Toolkit;

/**
* Schedule a task that executes once every second.
* Beep every second.
*/

public class AnnoyingBeep {


Toolkit toolkit;
Timer timer;

public AnnoyingBeep() {
toolkit = Toolkit.getDefaultToolkit();
timer = new Timer();
timer.schedule(new RemindTask(),
0, //initial delay
1*1000); //subsequent rate
}

class RemindTask extends TimerTask {


int numWarningBeeps = 3;

public void run() {


if (numWarningBeeps > 0) {
toolkit.beep();
System.out.format("Beep!%n");
numWarningBeeps--;
} else {
toolkit.beep();
System.out.format("Time's up!%n");
//timer.cancel(); //Not necessary because we call System.exit
System.exit(0); //Stops the AWT thread (and everything else)
}
}
}

public static void main(String args[]) {


System.out.format("About to schedule task.%n");
new AnnoyingBeep();
System.out.format("Task scheduled.%n");
}
}
Code-6.21: AnnoyingBeep.java

3 Build and run the project

Right click AnnoyingBeep project and select Run.


Observe the result in the Output window. (Figure-6.22 below)

About to schedule task.


Task scheduled.
Beep!
Beep!
Beep!
Time's up!
Figure-6.22: Result

return to top of the exercise

Summary

In this exercise, you have learned how to use Timer and TimerTask classes to schedule one-time or repeating tasks.

return to the top

Homework

1. The homework is to create a new NetBeans project called MyRunnableProject as following.

Create a class called MyCurrentDate that implements Runnable interface.


The MyCurrentDate class displays the current date and time 10 times, with 100 milli seconds interval - use sleep() method for
this interval.
Create a class called MyMain, which contans main() method, in which 3 instances of MyCurrentDate threads are being run.

You might also like