Unit 4 java
Multitasking: Multitasking is when a CPU is provided to execute multiple tasks at a time.
Multitasking involves often CPU switching between the tasks, so that users can collaborate with each
program together. Unlike multithreading, In multitasking, the processes share separate memory and
resources. As multitasking involves CPU switching between the tasks rapidly, So the little time is
needed in order to switch from the one user to
next.
Multithreading: Multithreading is a system in which many threads are created from a
process through which the computer power is increased. In multithreading, CPU is provided in order
to execute many threads from a process at a time, and in multithreading, process creation is
performed according to cost. Unlike multitasking, multithreading provides the same memory and
resources to the processes for
execution.
Let’s see the difference between multitasking and multithreading:
S.NO Multitasking Multithreading
While in multithreading, many threads are
In multitasking, users are allowed to
1. created from a process through which
perform many tasks by CPU.
computer power is increased.
Multitasking involves often CPU switching While in multithreading also, CPU switching is
2.
between the tasks. often involved between the threads.
In multitasking, the processes share While in multithreading, processes are
3.
separate memory. allocated the same memory.
The multitasking component involves While the multithreading component does not
4.
multiprocessing. involve multiprocessing.
In multitasking, the CPU is provided in While in multithreading also, a CPU is provided
5.
order to execute many tasks at a time. in order to execute many threads from a
S.NO Multitasking Multithreading
process at a time.
In multitasking, processes don’t share the
While in multithreading, each process shares
6. same resources, each process is allocated
the same resources.
separate resources.
Multitasking is slow compared to
7. While multithreading is faster.
multithreading.
In multitasking, termination of a process While in multithreading, termination of thread
8.
takes more time. takes less time.
Isolation and memory protection exist in Isolation and memory protection does not exist
9.
multitasking. in multithreading.
It helps in developing efficient operating
10. It helps in developing efficient programs.
systems.
Involves dividing a single process into multiple
Involves running multiple independent
11. threads that can execute concurrently
processes or tasks
Multiple processes or tasks run Multiple threads within a single process share
12. simultaneously, sharing the same the same memory space and resources
processor and resources
Threads share the same memory space and
Each process or task has its own memory
13. resources of the parent process
space and resources
14. Used to manage multiple processes and Used to manage multiple processes and
S.NO Multitasking Multithreading
improve system efficiency improve system efficiency
Examples: running multiple applications Examples: splitting a video encoding task into
15. on a computer, running multiple servers multiple threads, implementing a responsive
on a network user interface in an application
Life Cycle of Thread
Thread State
Life Cycle of Thread in Java is basically state transitions of a thread that starts from its birth and
ends on its death.
When an instance of a thread is created and is executed by calling start() method of Thread class,
the thread goes into runnable state.
When sleep() or wait() method is called by Thread class, the thread enters into non-runnable state.
From non-runnable state, thread comes back to runnable state and continues execution of
statements.
When the thread comes out of run() method, it dies. These state transitions of a thread are
called Thread life cycle in Java.
To work with threads in a program, it is important to identify thread state. So. let’s understand how
to identify thread states in Java thread life cycle.
Thread States in Java
A thread is a path of execution in a program that enters any one of the following five states during
its life cycle. The five states are as follows:
1. New
2. Runnable
3. Running
4. Blocked (Non-runnable state)
5. Dead
1. New (Newborn State): When we create a thread object using Thread class, thread is born and is
known to be in Newborn state. That is, when a thread is born, it enters into new state but the start()
method has not been called yet on the instance.
In other words, Thread object exists but it cannot execute any statement because it is not an
execution of thread. Only start() method can be called on a new thread; otherwise,
an IllegalThreadStateException will be thrown.
2. Runnable state: Runnable state means a thread is ready for execution. When the start() method is
called on a new thread, thread enters into a runnable state.
In runnable state, thread is ready for execution and is waiting for availability of the processor (CPU
time). That is, thread has joined queue (line) of threads that are waiting for execution.
If all threads have equal priority, CPU allocates time slots for thread execution on the basis of first-
come, first-serve manner. The process of allocating time to threads is known as time slicing. A
thread can come into runnable state from running, waiting, or new states.
3. Running state: Running means Processor (CPU) has allocated time slot to thread for its execution.
When thread scheduler selects a thread from the runnable state for execution, it goes into running
state. Look at the above figure.
In running state, processor gives its time to the thread for execution and executes its run method.
This is the state where thread performs its actual functions. A thread can come into running state
only from runnable state.
A running thread may give up its control in any one of the following situations and can enter into the
blocked state.
a) When sleep() method is invoked on a thread to sleep for specified time period, the thread is out
of queue during this time period. The thread again reenters into the runnable state as soon as this
time period is elapsed.
b) When a thread is suspended using suspend() method for some time in order to satisfy some
conditions. A suspended thread can be revived by using resume() method.
c) When wait() method is called on a thread to wait for some time. The thread in wait state can be
run again using notify() or notifyAll() method.
4. Blocked state: A thread is considered to be in the blocked state when it is suspended, sleeping, or
waiting for some time in order to satisfy some condition.
5. Dead state: A thread dies or moves into dead state automatically when its run() method
completes the execution of statements. That is, a thread is terminated or dead when a thread comes
out of run() method. A thread can also be dead when the stop() method is called.
During the life cycle of thread in Java, a thread moves from one state to another state in a variety of
ways. This is because in multithreading environment, when multiple threads are executing, only one
thread can use CPU at a time.
Create a Thread
Thread can be referred to as a lightweight process. Thread uses fewer resources to create and exist
in the process; thread shares process resources. The main thread of Java is the thread that is started
when the program starts. The slave thread is created as a result of the main thread. This is the last
thread to complete execution.
A thread can programmatically be created by:
1. Implementing the java.lang.Runnable interface.
2. Extending the java.lang.Thread class.
You can create threads by implementing the runnable interface and overriding the run() method.
Then, you can create a thread object and call the start() method.
Thread Class:
The Thread class provides constructors and methods for creating and operating on threads. The
thread extends the Object and implements the Runnable interface.
// start a newly created thread.
// Thread moves from new state to runnable state
// When it gets a chance, executes the target run() method
public void start()
Runnable interface:
Any class with instances that are intended to be executed by a thread should implement the
Runnable interface. The Runnable interface has only one method, which is called run().
// Thread action is performed
public void run()
Benefits of creating threads :
When compared to processes, Java Threads are more lightweight; it takes less time and
resources to create a thread.
Threads share the data and code of their parent process.
Thread communication is simpler than process communication.
Context switching between threads is usually cheaper than switching between processes.
Calling run() instead of start()
The common mistake is starting a thread using run() instead of start() method.
Thread myThread = new Thread(MyRunnable());
myThread.run(); //should be start();
The run() method is not called by the thread you created. Instead, it is called by the thread that
created the myThread.
Example 1: By using Thread Class
Java
import java.io.*;
class GFG extends Thread {
public void run()
System.out.print("Welcome to GeeksforGeeks.");
public static void main(String[] args)
GFG g = new GFG(); // creating thread
g.start(); // starting thread
Output
Welcome to GeeksforGeeks.
Example 2: By implementing Runnable interface
Java
import java.io.*;
class GFG implements Runnable {
public static void main(String args[])
{
// create an object of Runnable target
GFG gfg = new GFG();
// pass the runnable reference to Thread
Thread t = new Thread(gfg, "gfg");
// start the thread
t.start();
// get the name of the thread
System.out.println(t.getName());
@Override public void run()
System.out.println("Inside run method");
Output
gfg
Inside run method
Inter-thread Communication
Inter-thread communication or Co-operation is all about allowing synchronized threads to
communicate with each other.
Cooperation (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:
o wait()
o notify()
o notifyAll()
1) wait() method
The wait() method causes current thread to release the lock and wait until either another thread
invokes the notify() method or the notifyAll() method for this object, or a specified amount of time
has elapsed.
The current thread must own this object's monitor, so it must be called from the synchronized
method only otherwise it will throw exception.
Method Description
public final void wait()throws InterruptedException It waits until object is notified.
public final void wait(long timeout)throws InterruptedException It waits for the specified amount of time.
2) notify() method
The notify() method wakes up a single thread that is waiting on this object's monitor. If any threads
are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs
at the discretion of the implementation.
Syntax:
1. public final void notify()
3) notifyAll() method
Wakes up all threads that are waiting on this object's monitor.
Syntax:
1. public final void notifyAll()
Understanding the process of inter-thread communication
The point to point explanation of the above diagram is as follows:
1. Threads enter to acquire lock.
2. Lock is acquired by on thread.
3. Now thread goes to waiting state if you call wait() method on the object. Otherwise it
releases the lock and exits.
4. If you call notify() or notifyAll() method, thread moves to the notified state (runnable state).
5. Now thread is available to acquire lock.
6. After completion of the task, thread releases the lock and exits the monitor state of the
object.
Why wait(), notify() and notifyAll() methods are defined in Object class not Thread class?
It is because they are related to lock and object has a lock.
Difference between wait and sleep?
Let's see the important differences between wait and sleep methods.
wait() sleep()
The wait() method releases the lock. The sleep() method doesn't release the lock.
It is a method of Object class It is a method of Thread class
It is the non-static method It is the static method
It should be notified by notify() or notifyAll() methods After the specified amount of time, sleep is completed.
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.
Points to remember for Daemon Thread in Java
o It provides services to user threads for background supporting tasks. It has no role in life
than to serve user threads.
o Its life depends on user threads.
o It is a low priority thread.
Why JVM terminates the daemon thread if there is no user thread?
The sole purpose of the daemon thread is that it provides services to user thread for background
supporting task. If there is no user thread, why should JVM keep running this thread. That is why
JVM terminates the daemon thread if there is no user thread.
Methods for Java Daemon thread by Thread class
The java.lang.Thread class provides two methods for java daemon thread.
No. Method Description
1) public void setDaemon(boolean is used to mark the current thread as daemon thread or user
status) thread.
2) public boolean isDaemon() is used to check that current is daemon.
Simple example of Daemon thread in java
File: MyThread.java
1. public class TestDaemonThread1 extends Thread{
2. public void run(){
3. if(Thread.currentThread().isDaemon()){//checking for daemon thread
4. System.out.println("daemon thread work");
5. }
6. else{
7. System.out.println("user thread work");
8. }
9. }
10. public static void main(String[] args){
11. TestDaemonThread1 t1=new TestDaemonThread1();//creating thread
12. TestDaemonThread1 t2=new TestDaemonThread1();
13. TestDaemonThread1 t3=new TestDaemonThread1();
14.
15. t1.setDaemon(true);//now t1 is daemon thread
16.
17. t1.start();//starting threads
18. t2.start();
19. t3.start();
20. }
21. }
Output:
daemon thread work
user thread work
user thread work
Note: If you want to make a user thread as Daemon, it must not be started otherwise it will throw
IllegalThreadStateException.
File: MyThread.java
1. class TestDaemonThread2 extends Thread{
2. public void run(){
3. System.out.println("Name: "+Thread.currentThread().getName());
4. System.out.println("Daemon: "+Thread.currentThread().isDaemon());
5. }
6.
7. public static void main(String[] args){
8. TestDaemonThread2 t1=new TestDaemonThread2();
9. TestDaemonThread2 t2=new TestDaemonThread2();
10. t1.start();
11. t1.setDaemon(true);//will throw exception here
12. t2.start();
13. }
14. }
Output:
exception in thread main: java.lang.IllegalThreadStateException
Thread Group
Java provides a convenient way to group multiple threads in a single object. In such a way, we
can suspend, resume or interrupt a group of threads by a single method call.
Note: Now suspend(), resume() and stop() methods are deprecated.
Java thread group is implemented by java.lang.ThreadGroup class.
A ThreadGroup represents a set of threads. A thread group can also include the other thread
group. The thread group creates a tree in which every thread group except the initial thread
group has a parent.
A thread is allowed to access information about its own thread group, but it cannot access the
information about its thread group's parent thread group or any other thread groups.
Constructors of ThreadGroup class
There are only two constructors of ThreadGroup class.
No. Constructor Description
1) ThreadGroup(String name) creates a thread group with given name.
2) ThreadGroup(ThreadGroup parent, String creates a thread group with a given parent
name) group and name.
Methods of ThreadGroup class
There are many methods in ThreadGroup class. A list of ThreadGroup methods is given below.
S.N. Modifier and Method Description
Type
1) void checkAccess() This method determines if the currently
running thread has permission to modify
the thread group.
2) int activeCount() This method returns an estimate of the
number of active threads in the thread
group and its subgroups.
3) int activeGroupCount() This method returns an estimate of the
number of active groups in the thread
group and its subgroups.
4) void destroy() This method destroys the thread group
and all of its subgroups.
5) int enumerate(Thread[] list) This method copies into the specified array
every active thread in the thread group
and its subgroups.
6) int getMaxPriority() This method returns the maximum priority
of the thread group.
7) String getName() This method returns the name of the
thread group.
8) ThreadGroup getParent() This method returns the parent of the
thread group.
9) void interrupt() This method interrupts all threads in the
thread group.
10) boolean isDaemon() This method tests if the thread group is a
daemon thread group.
11) void setDaemon(boolean This method changes the daemon status of
daemon) the thread group.
12) boolean isDestroyed() This method tests if this thread group has
been destroyed.
13) void list() This method prints information about the
thread group to the standard output.
14) boolean parentOf(ThreadGroup g This method tests if the thread group is
either the thread group argument or one
of its ancestor thread groups.
15) void suspend() This method is used to suspend all threads
in the thread group.
16) void resume() This method is used to resume all threads
in the thread group which was suspended
using suspend() method.
17) void setMaxPriority(int pri) This method sets the maximum priority of
the group.
18) void stop() This method is used to stop all threads in
the thread group.
19) String toString() This method returns a string
representation of the Thread group.
Let's see a code to group multiple threads.
1. ThreadGroup tg1 = new ThreadGroup("Group A");
2. Thread t1 = new Thread(tg1,new MyRunnable(),"one");
3. Thread t2 = new Thread(tg1,new MyRunnable(),"two");
4. 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.
1. Thread.currentThread().getThreadGroup().interrupt();
ThreadGroup Example
File: ThreadGroupDemo.java
1. public class ThreadGroupDemo implements Runnable{
2. public void run() {
3. System.out.println(Thread.currentThread().getName());
4. }
5. public static void main(String[] args) {
6. ThreadGroupDemo runnable = new ThreadGroupDemo();
7. ThreadGroup tg1 = new ThreadGroup("Parent ThreadGroup");
8.
9. Thread t1 = new Thread(tg1, runnable,"one");
10. t1.start();
11. Thread t2 = new Thread(tg1, runnable,"two");
12. t2.start();
13. Thread t3 = new Thread(tg1, runnable,"three");
14. t3.start();
15.
16. System.out.println("Thread Group Name: "+tg1.getName());
17. tg1.list();
18.
19. }
20. }
Output:
one
two
three
Thread Group Name: Parent ThreadGroup
java.lang.ThreadGroup[name=Parent ThreadGroup,maxpri=10]
Generic programming
Java Generics is a set of related methods or a set of similar types. Generics allow types Integer,
String, or even user-defined types to be passed as a parameter to classes, methods, or interfaces.
Generics are mostly used by classes like HashSet or HashMap.
Advantages of using generics
Generics ensure compile-time safety which allows the programmer to catch the invalid
types while compiling the code.
Java Generics helps the programmer to reuse the code for whatever type he/she wishes. For
instance, a programmer writes a generic method for sorting an array of objects. Generics
allow the programmer to use the same method for Integer arrays, Double arrays, and even
String arrays.
Another advantage of using generics is that Individual typecasting isn’t required. The
programmer defines the initial type and then lets the code do its job.
It allows us to implement non-generic algorithms.
Constraints
Java Generics does not support sub-typing.
You cannot create generic arrays in Java Generics.
Types of Java Generics
Generic method: Generic Java method takes a parameter and returns some value after
performing a task. It is exactly like a normal function, however, a generic method
has type parameters which are cited by actual type. This allows the generic method to be
used in a more general way. The compiler takes care of the type of safety which enables
programmers to code easily since they do not have to perform long, individual type castings.
Generic classes: A generic class is implemented exactly like a non-generic class. The only
difference is that it contains a type parameter section. There can be more than one type of
parameter, separated by a comma. The classes, which accept one or more parameters, are
known as parametrized classes or parameterized types.
Example: Create a Generics Method
class Main {
public static void main(String[] args) {
// initialize the class with Integer data
DemoClass demo = new DemoClass();
// generics method working with String
demo.<String>genericsMethod("Java Programming");
// generics method working with integer
demo.<Integer>genericsMethod(25);
}
}
class DemoClass {
// creae a generics method
public <T> void genericsMethod(T data) {
System.out.println("Generics Method:");
System.out.println("Data Passed: " + data);
}
}
Run Code
Output
Generics Method:
Data Passed: Java Programming
Generics Method:
Data Passed: 25
Example: Create a Generics Class
class Main {
public static void main(String[] args) {
// initialize generic class
// with Integer data
GenericsClass<Integer> intObj = new GenericsClass<>(5);
System.out.println("Generic Class returns: " + intObj.getData());
// initialize generic class
// with String data
GenericsClass<String> stringObj = new GenericsClass<>("Java Programming");
System.out.println("Generic Class returns: " + stringObj.getData());
}
}
// create a generics class
class GenericsClass<T> {
// variable of T type
private T data;
public GenericsClass(T data) {
this.data = data;
// method that return T type variable
public T getData() {
return this.data;
Run Code
Output
Generic Class returns: 5
Generic Class returns: Java Programming