0% found this document useful (0 votes)
24 views

Unit 4 Java

The document discusses multitasking and multithreading. It defines them, compares their key differences, and describes the life cycle of a thread in Java including the different states a thread can be in.

Uploaded by

vivek kumar
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views

Unit 4 Java

The document discusses multitasking and multithreading. It defines them, compares their key differences, and describes the life cycle of a thread in Java including the different states a thread can be in.

Uploaded by

vivek kumar
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 22

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

You might also like