Unit 2 - Java Programming
Unit 2 - Java Programming
Advantage of Thread
Easier to program
o 1 thread per task
Can provide better performance
o Thread only runs when needed
o No polling to decide what to do
Multiple threads can share resources
Utilizemultiple processors if available
MULTITHREADING
Java is a multi-threaded programming language which means we can develop multi-threaded program using
Java. A multi-threaded program contains two or more parts that can run concurrently and each part can handle
a different task at the same time making optimal use of the available resources specially when your computer
has multiple CPUs.
By definition, multitasking is when multiple processes share common processing resources such as a CPU.
Multi-threading extends the idea of multitasking into applications where you can subdivide specific operations
within a single application into individual threads. Each of the threads can run in parallel. The OS divides
processing time not only among different applications, but also among each thread within an application.
Multi-threading enables you to write in a way where multiple activities can proceed concurrently in the same
program.
THREAD PRIORITIES
Every Java thread has a priority that helps the operating system determine the order in which threads are
scheduled.
Java thread priorities are in the range between MIN_PRIORITY (a constant of 1) and MAX_PRIORITY (a
constant of 10). By default, every thread is given priority NORM_PRIORITY (a constant of 5).
Threads with higher priority are more important to a program and should be allocated processor time before
lower-priority threads. However, thread priorities cannot guarantee the order in which threads execute and are
very much platform dependent.
Where, threadObj is an instance of a class that implements the Runnable interface and threadName is the name
given to the new thread.
Or just create only object of Thread class like
Thread threadObj = new Thread();
Step 3
Once a Thread object is created, you can start it by calling start() method, which executes a call to run( )
method. Following is a simple syntax of start() method −
void start();
call this method with the help of Thread object. Like:
ThreadObj.start();
Syntax:
class A implements Runnable
{
public void run()
{
// code that you want to attach with thread
}
}
public class Example
{
public static void main(String args[])
{
Thread t1= new Thread( new A());
t1.start();
}
}
Example
Here is an example that creates a new thread and starts running it −
class A implements Runnable{
public void run(){
for(int i=0;i<=10;i++)
System.out.println("Thread A "+i);
}
}
class B implements Runnable{
public void run(){
for(int i=0;i<=10;i++)
System.out.println("Thread B "+i);
}
}
public class MyThread{
public static void main(String args[]){
Thread t1= new Thread(new A());
Thread t2= new Thread(new B());
t1.start();
t2.start();
}
}
This will produce the following result −
Output:
Create a Thread by Extending a Thread Class
The second way to create a thread is to create a new class that extends Thread class using the following two
simple steps. This approach provides more flexibility in handling multiple threads created using available
methods in Thread class.
Step 1
You will need to override run( ) method available in Thread class. This method provides an entry point for the
thread and you will put your complete business logic inside this method. Following is a simple syntax of run()
method −
public void run( )
Step 2
Once Thread object is created, you can start it by calling start() method, which executes a call to run( ) method.
Following is a simple syntax of start() method −
void start( );
call this method with the help of class object which is extends by Thread object. Like:
Obj.start();
Syntax:
class A extends Thread
{
public void run()
{
// code that you want to attach with thread
}
}
public class Example
{
public static void main(String args[])
{
A t1= new A();
t1.start();
}
}
Example
Here is the preceding program rewritten to extend the Thread −
Output:
Synchronization in Java
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.
Multi-threaded programs may often come to a situation where multiple threads try to access the same resources
and finally produce erroneous and unforeseen results.
So it needs to be made sure by some synchronization method that only one thread can access the resource at
a given point of time.
Java provides a way of creating threads and synchronizing their task by using synchronized blocks.
Synchronized blocks in Java are marked with the synchronized keyword. A synchronized block in Java is
synchronized on some object. All synchronized blocks 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.
Following is the general form of a synchronized block:
1. 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)
Mutual Exclusive
Mutual Exclusive helps keep threads from interfering with one another while sharing data. This can be done
by three ways in java:
1. by synchronized method
2. by synchronized block
3. by static synchronization
class TestSynchronization1{
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();
}
}
Output: 5
100
10
200
15
300
20
400
25
500
}
}
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 TestSynchronization2 {
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();
}
}
Output:
5
10
15
20
25
100
200
300
400
500
Synchronized block
Here we write code inside the synchronized block
Whole program will worked parallel but only that particularcode will run serially(Synchronized)
Syntax:
Object o1= new Object();
Synchronized(o1) //acquire lock on o1 on entry
{ //hold lock on o1 in block
// Release lock on x on exit
}
Understanding the problem without Synchronization
In this example, there is no synchronization, so output is inconsistent. Let's see the example:
Example:
import java.util.Scanner;
class Account {
private int bal;
public Account(int b) {
this.bal = b;
}
public boolean isSufficiantBal(int am) {
if (bal >= am) {
return (true);
} else {
return (false);
}
}
public void withdrowal(int amt) {
bal = bal - amt;
System.out.println("Your Current bal " + bal);
}
}
class Customer implements Runnable {
private String name ;
private Account acc;
public Customer(Account a1, String n) {
acc = a1;
this.name = n;
}
public void run() {
Scanner kb = new Scanner(System.in);
System.out.println(name + " Enter the withdrawl amount ");
int amt = kb.nextInt();
if (acc.isSufficiantBal(amt)) {
System.out.println(name);
acc.withdrowal(amt);
} else {
System.out.println("insufficient bal");
}
}
}
public class SynchThread {
public static void main(String args[]) {
Account a1 = new Account(1000);
Customer c1 = new Customer(a1, "Jack");
Customer c2 = new Customer(a1, 'John");
Thread t1 = new Thread(c1);
Thread t2 = new Thread(c2);
t1.start();
t2.start();
}
}
In previous example have two threads and both are access same resource (Account)
In that case may be data corruption problem occurs
Output of the program like that;
Output:
John Enter the withdrawl amount
Jack Enter the withdrawl amount
700
500
Jack
Your Current bal 300
John
Your Current bal -300
THREAD SCHEDULING
Thread scheduler in java is the part of the JVM that decides which thread should run. There is no guarantee
that which runnable thread will be chosen to run by the thread scheduler. Only one thread at a time can run in
a single process.
The thread scheduler mainly uses preemptive or time slicing scheduling to schedule the threads. Difference
between preemptive scheduling and time slicing
Under preemptive scheduling, the highest priority task executes until it enters the waiting or dead states or a
higher priority task comes into existence. Under time slicing, a task executes for a predefined slice of time
and then reenters the pool of ready tasks. The scheduler then determines which task should execute next, based
on priority and other factors.
Priority Thread
It decide as a number . We can specify the priority of each thread relative to other thread. Those threads having
higher priority get greater access of available sources then lower priority threads. Java thread inherit its priority
from the thread class. Priority already set by default 5
We can change the priority of thread using setPriority() function. Value of priority also returned by the
getPriority() function
Example: Thread t1= new Thread();
t1.setPriority(7);
Priority lie between 0 to 10 Higher no has a higher priority
Example:
class A extends Thread
{
public void run()
{
for(int i=0;i<=10;i++)
{
System.out.println("Thread A "+i);
}
}
}
class B extends Thread
{
Downloaded from www.rgpvnotes.in
t1.setPriority(10);
t2.setPriority(6);
t1.start();
t2.start();
}
}
Daemon Thread
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. There are many java daemon threads running automatically e.g. gc, finalizer etc.
You can see all the detail by typing the jconsole in the command prompt. The jconsole tool provides
information about the loaded classes, memory usage, running threads etc.
t1.start();//starting threads
t2.start();
t3.start();
}
}
Output
daemon thread work
user thread work
user thread work
EXCEPTION HANDLING
The exception handling in java is one of the powerful mechanism to handle the runtime errors so that normal
flow of the application can be maintained.
In this page, we will learn about java exception, its type and the difference between checked and unchecked
exceptions.
What is exception
Dictionary Meaning: Exception is an abnormal condition.
In java, exception is an event that disrupts the normal flow of the program. It is an object which is thrown at
runtime.
What is exception handling
Exception Handling is a mechanism to handle runtime errors such as ClassNotFound, IO, SQL, Remote etc.
Advantage of Exception Handling
The core advantage of exception handling is to maintain the normal flow of the application. Exception
normally disrupts the normal flow of the application that is why we use exception handling. Let's take a
scenario:
statement 1;
statement 2;
statement 3;
statement 4;
statement 5;//exception occurs
statement 6;
statement 7;
statement 8;
statement 9;
statement 10;
Suppose there is 10 statements in your program and there occurs an exception at statement 5, rest of the code
will not be executed i.e. statement 6 to 10 will not run. If we perform exception handling, rest of the statement
will be executed. That is why we use exception handling in java.
Java try-catch
As displayed in the above example, rest of the code is not executed (in such case, rest of the code... statement
is not printed).
There can be 100 lines of code after exception. So all the code after exception will not be executed.
Solution by exception handling
Let's see the solution of above problem by java try-catch block.
public class Testtrycatch2
{
public static void main(String args[])
{
try
{
int data=50/0;
}catch(ArithmeticException e)
{
System.out.println(e);
}
System.out.println("rest of the code...");
}
}
Output:
Exception in thread main java.lang.ArithmeticException:/ by zero
rest of the code...
Now, as displayed in the above example, rest of the code is executed i.e. rest of the code... statement is printed.
The JVM firstly checks whether the exception is handled or not. If exception is not handled, JVM provides a
default exception handler that performs the following tasks:
Prints out exception description.
Prints the stack trace (Hierarchy of methods where the exception occurred).
Causes the program to terminate.
But if exception is handled by the application programmer, normal flow of the application is maintained i.e.
rest of the code is executed.
class TestMultipleCatchBlock1
{
public static void main(String args[])
{
try
{
int a[]=new int[5];
a[5]=30/0;
}
catch(Exception e)
{
System.out.println("common task completed");
}
catch(ArithmeticException e)
{
System.out.println("task1 is completed");
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("task 2 completed");
}
System.out.println("rest of the code...");
}
}
Output:
Compile-time error
class Excep6
{
public static void main(String args[])
{
try
{
try
{
System.out.println("going to divide");
int b =39/0;
}catch(ArithmeticException e)
{System.out.println(e);}
try
{
int a[]=new int[5];
a[5]=4;
}catch(ArrayIndexOutOfBoundsException e)
{System.out.println(e);}
System.out.println("other statement);
}catch(Exception e)
{System.out.println("handeled");}
System.out.println("normal flow..");
}
}
Java finally block
Java finally block is a block that is used to execute important code such as closing connection, stream etc.
Java finally block is always executed whether exception is handled or not.
Java finally block follows try or catch block.
Note: If you don't handle exception, before terminating the program, JVM executes finally block(if any).
Why use java finally
Finally block in java can be used to put "cleanup" code such as closing a file, closing connection etc.
class TestFinallyBlock
{
public static void main(String args[]){
try
{
int data=25/5;
System.out.println(data);
}
catch(NullPointerException e)
{System.out.println(e);
}
finally
{
System.out.println("finally block is always executed");
}
System.out.println("rest of the code...");
}
}
Output:
5
finally block is always executed
rest of the code...
Case 2
Let's see the java finally example where exception occurs and not handled.
class TestFinallyBlock1
{
public static void main(String args[]){
try
{
int data=25/0;
System.out.println(data);
}
catch(NullPointerException e)
{
System.out.println(e);
}
Finally
{
System.out.println("finally block is always executed");
}
System.out.println("rest of the code...");
}
}
Output:
finally block is always executed
Exception in thread main java.lang.ArithmeticException:/ by zero
Case 3
Let's see the java finally example where exception occurs and handled.
Rule: For each try block there can be zero or more catch blocks, but only one finally block.
Note: The finally block will not be executed if program exits(either by calling System.exit() or by causing a
fatal error that causes the process to abort).
Java throw keyword
The Java throw keyword is used to explicitly throw an exception. We can throw either checked or uncheked
exception in java by throw keyword. The throw keyword is mainly used to throw custom exception.
The syntax of java throw keyword is given below.
throw exception;
Let's see the example of throw IOException.
throw new IOException("sorry device error);
java throw keyword example
In this example, we have created the validate method that takes integer value as a parameter. If the age is less
than 18, we are throwing the ArithmeticException otherwise print a message welcome to vote.
In the above example exception occurs in m() method where it is not handled,so it is propagated to previous
n() method where it is not handled, again it is propagated to p() method where exception is handled.
Exception can be handled in any method in call stack either in main() method,p() method,n() method or m()
method.
Rule: By default, Checked Exceptions are not forwarded in calling chain (propagated).
m.method();
System.out.println("normal flow...");
}
}
Output:device operation performed
normal flow...
b) Program if exception occurs
import java.io.*;
class M
{
void method()throws IOException
{
throw new IOException("device error");
}}
class Testthrows4
{
public static void main(String args[])throws IOException//declare exception
{
M m=new M();
m.method();
System.out.println("normal flow...");
}
}
Output:Runtime Exception