You are on page 1of 26

CHAPTER 1

Multi-threading
Multitasking in Java
 Multitasking is the ability of the CPU to perform
multiple tasks simultaneously. There will be
continuous context switching of CPU between the
tasks which is rapid and hence results in better
performance. The CPU collaborates between the
users and performs multiple tasks effectively.
Types of multitasking in Java
There are 2 types of multitasking in Java:
 Process-based multitasking: More than 1 process runs concurrently.
Eg: Executing an excel spreadsheet while running a word processor.
 Thread-based multitasking: More than 1 thread executes
concurrently. A thread executes different parts of the same program.
Eg: Formatting a text in a word processor and printing it at the same
time. Even though each thread has a different execution path for the
same process, all threads share the same resource and memory.
Multi-threaded programming

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.
Advantage of the Multi-threading

It enables you to write very efficient programs that maximizes the CPU utilization and reduces
the idle time.

Most I/O devices such as network ports, disk drives or the keyboard are much slower than CPU

A program will spend much of it time just send and receive the information to or from the
devices, which in turn wastes the CPU valuable time.

By using the multithreading, your program can perform another task during this idle time.

For example, while one part of the program is sending a file over the internet, another part can
read the input from the keyboard, while other part can buffer the next block to send.

It is possible to run two or more threads in multiprocessor or multi core systems simultaneously.
Life Cycle of a Thread
A thread goes through various stages in its life cycle. For example, a thread is born,
started, runs, and then dies. The following diagram shows the complete life cycle of a
thread.
Following are the stages of the life cycle

New − A new thread begins its life cycle in the new state. It remains in this state until
the program starts the thread. It is also referred to as a born thread.
 Runnable − After a newly born thread is started, the thread becomes runnable. A thread

in this state is considered to be executing its task.


 Waiting − Sometimes, a thread transitions to the waiting state while the thread waits for

another thread to perform a task. A thread transitions back to the runnable state only
when another thread signals the waiting thread to continue executing.

Timed Waiting − A runnable thread can enter the timed waiting state for a specified
interval of time. A thread in this state transitions back to the runnable state when that
time interval expires or when the event it is waiting for occurs.
 Terminated (Dead) − A runnable thread enters the terminated state when it completes

its task or otherwise terminates.


Creation of Thread

Creating the threads in the Java is simple. The threads can be implemented in the form
of object
 that contains a method "run()". The "run()" method is the heart and soul of any thread. It

makes up the
 entire body of the thread and is the only method in which the thread behavior can be

implemented.
 There are two ways to create thread.

1. Declare a class that extends the Thread class and override the run() method.
2. Declare a class that implements the Runnable interface which contains the run() method
.
Extending the thread class

We can make our thread by extending the Thread class of


java.lang.Thread class. This gives us access to all the methods of the
Thread. It includes the following steps:
I. Declare the class as Extending the Thread class.
II. Override the "run()" method that is responsible for running the thread.
III. Create a thread and call the "start()" method to instantiate the Thread
Execution.
Declaring the class
TheThread class can be declared as follows:
class MyThread extends Thread
{
-----------------------
----------------------
----------------------
----------------------
}
Overriding the method run()
The run() is the method of the Thread. We can override this as follows:
public void run()
{
----------------
----------------
----------------
}
Starting the new Thread
To actually create and run an instance of the thread class, we
must write the following:
MyThread a = new MyThread(); // creating the Thread
a.start(); // Starting the Thread
class A extends Thread
{
public void run()
{
for(int i=1;i<=5;i++)
{
System.out.println("From Threaad A :i="+i);
}
System.out.println("Exit from Thread A");
}
}
class ThreadTest
{
public static void main(String args[])
{
System.out.println("main thread started");
A a=new A();
a.start();
System.out.println("main thread ended");
}
Common methods of thread
class

public void run(): is used to perform action for a thread.

public void start(): starts the execution of the thread. JVM calls the run() method
on the thread.

public void sleep(long miliseconds): Causes the currently executing thread to sleep
(temporarily cease execution) for the specified number of milliseconds.

public int getPriority(): returns the priority of the thread.

public int setPriority(int priority): changes the priority of the thread.

public String getName(): returns the name of the thread.

public void setName(String name): changes the name of the thread.
Implementing Runnable Interface
The Runnable interface contains the run() method that is required for
implementing the threads in our program. To do this we must perform
the following steps:
I. Declare a class as implementing the Runnable interface
II. Implement the run() method
III. Create a Thread by defining an object that is instantiated from this
"runnable" class as the target of the thread
IV. Call the thread's start() method to run the thread.
class x implements Runnable
{
//1 STEP
public void run()
{
//2 STEP
for(int i=0;i<=5;i++)
System.out.println("The Thread x is:"+i);
System.out.println("End of the Thread x");
}
}
class RunnableTest
{
public static void main(String args[])
{
x r=new x();
Thread threadx=new Thread(r);
threadx.start();
System.out.println("The end of the main thread");}
}
class A implements Runnable
{
public void run()
{
for(int i=1;i<=5;i++)
{
System.out.println("From Threaad A :i="+i);
}
System.out.println("Exit from Thread A");
}
}
class ThreadTest
{
public static void main(String args[])
{
System.out.println("main thread started");
A a=new A();
Thread t1=new Thread(a);
t1.start();
System.out.println("main thread ended");
}
Synchronization


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.

When two or more threads need access to a shared resource, they need
some way to ensure that the resource will be used by only one thread at
a time. The process by which this is achieved is called synchronization.
Key to synchronization is the concept of the monitor (also called a
semaphore). A monitor is an object that is used as a mutually
exclusive lock, or mutex. Only one thread can own a monitor at
a given time. When a thread acquires a lock, it is said to have
entered the monitor. All other threads attempting to enter the
locked monitor will be suspended until the first thread exits the
monitor. These other threads are said to be waiting for the
monitor. A thread that owns a monitor can reenter the same
monitor if it so desires.
Approaches:
 Using synchronized Method

Using synchronized Statement
Using Synchronized Methods
 Synchronization is easy in Java, because all objects have their own implicit
monitor associated with them.
 To enter an object’s monitor, just call a method that has been modified with the
synchronized keyword.

While a thread is inside a synchronized method, all other threads that try to call
it (or any other synchronized method) on the same instance have to wait.

To exit the monitor and relinquish control of the object to the next waiting
thread, the owner of the monitor simply returns from the synchronized method.
class data
{
public void display(String name)
{
System.out.println("hello"+name);
}
}
class A implements Runnable
{
public void run()
{
System.out.println("From Threaad A");
data d=new data();
d.display(" thread a");
System.out.println("Exit from Thread A");
}
}
class B implements Runnable
{
public void run()
{
System.out.println("From Threaad B");
data d=new data();
d.display(" thread b");
System.out.println("Exit from Thread B");
}
}
public class JavaApplication2
{
public static void main(String[] args)
{
A a=new A();
B b=new B();
Thread t1=new Thread(a);
Thread t2=new Thread(b);
t1.start();
t2.start();
}
}
To fix the preceding program, we must serialize access to display( ). That is, we
must restrict its access to only one thread at a time. To do this, we simply need
to precede display( )’s definition with the keyword synchronized, as shown
here:
class data {
synchronized void display(String msg) {
...
This prevents other threads from entering display( ) while another thread is using
it.
The synchronized Statement
While creating synchronized methods within classes that we create is an easy and effective means of
achieving synchronization, it will not work in all cases. We have to put calls to the methods defined
by the class inside a synchronized block.
Syntax:
synchronized(object)
{
// statements to be synchronized
}
Here, object is a reference to the object being synchronized. A synchronized block ensures that a call
to a method that is a member of object occurs only after the current thread has successfully entered
object’s monitor.

You might also like