Unit 4 Java
Unit 4 Java
next.
execution.
Multitasking involves often CPU switching While in multithreading also, CPU switching is
2.
between the tasks. often involved between the threads.
The multitasking component involves While the multithreading component does not
4.
multiprocessing. involve multiprocessing.
process at a time.
Isolation and memory protection exist in Isolation and memory protection does not exist
9.
multitasking. in multithreading.
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
14. Used to manage multiple processes and Used to manage multiple processes and
S.NO Multitasking Multithreading
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 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.
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
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.
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.
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().
When compared to processes, Java Threads are more lightweight; it takes less time and
resources to create a thread.
Context switching between threads is usually cheaper than switching between processes.
The run() method is not called by the thread you created. Instead, it is called by the thread that
created the myThread.
Java
import java.io.*;
System.out.print("Welcome to GeeksforGeeks.");
Output
Welcome to GeeksforGeeks.
Java
import java.io.*;
t.start();
System.out.println(t.getName());
Output
gfg
Inter-thread Communication
Inter-thread communication or Co-operation is all about allowing synchronized threads to
communicate with each other.
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(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:
3) notifyAll() method
Syntax:
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).
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?
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.
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.
o It provides services to user threads for background supporting tasks. It has no role in life
than to serve user threads.
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.
The java.lang.Thread class provides two methods for java daemon thread.
1) public void setDaemon(boolean is used to mark the current thread as daemon thread or user
status) thread.
File: MyThread.java
5. }
6. else{
8. }
9. }
14.
16.
18. t2.start();
19. t3.start();
20. }
21. }
Output:
File: MyThread.java
3. System.out.println("Name: "+Thread.currentThread().getName());
4. System.out.println("Daemon: "+Thread.currentThread().isDaemon());
5. }
6.
10. t1.start();
12. t2.start();
13. }
14. }
Output:
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.
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.
There are many methods in ThreadGroup class. A list of ThreadGroup methods is given below.
12) boolean isDestroyed() This method tests if this thread group has
been destroyed.
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.
1. Thread.currentThread().getThreadGroup().interrupt();
ThreadGroup Example
File: ThreadGroupDemo.java
3. System.out.println(Thread.currentThread().getName());
4. }
8.
10. t1.start();
11. Thread t2 = new Thread(tg1, runnable,"two");
12. t2.start();
14. t3.start();
15.
17. tg1.list();
18.
19. }
20. }
Output:
one
two
three
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.
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.
Constraints
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.
class DemoClass {
Output
Generics Method:
Data Passed: Java Programming
Generics Method:
Data Passed: 25
}
}
class GenericsClass<T> {
// variable of T type
private T data;
this.data = data;
public T getData() {
return this.data;
Run Code
Output