Synchronization between threads in Java can be acheived by using Synchronized
key word. Synchronized
key world allows one thread at a time to access a method, variable or an object such that making other threads to wait until one finishes its work or get terminated.
There are two ways of using synchronized key word in Java.
1. Synchronized Methods
2. Synchronized Blocks
Synchronized Method
Firstly we will see how to use synchronized key word and what are its benefits by a simple example program. The below is a simple example program which reserves seats. We have three classes SeatReservation as main class, Person a thread class and Reservation which have the reserveSeat method.
ThreadSynchronization
class SeatReservation
{
public static void main(String[] args)
{
Reservation reserve = new Reservation(); // LINE A
Person thread1 = new Person(reserve, 5); // LINE B
thread1.start();
Person thread2 = new Person(reserve, 4);
thread2.start();
Person thread3 = new Person(reserve, 2);
thread3.start();
}
}
class Reservation
{
static int availableSeats = 10;
synchronized void reserveSeat(int requestedSeats) // LINE D
{
System.out.println(Thread.currentThread().getName() + " entered.");
System.out.println("Availableseats : " + availableSeats + " Requestedsetas : " + requestedSeats);
if (availableSeats >= requestedSeats)
{
System.out.println("Seat Available. Reserve now :-)");
try
{
Thread.sleep(100); // LINE E
}
catch (InterruptedException e)
{
System.out.println("Thread interrupted");
}
System.out.println(requestedSeats + " seats reserved.");
availableSeats = availableSeats - requestedSeats;
}
else
{
System.out.println("Requested seats not available :-(");
}
System.out.println(Thread.currentThread().getName() + " leaving.");
System.out.println("----------------------------------------------");
}
}
class Person extends Thread
{
Reservation reserve;
int requestedSeats;
public Person(Reservation reserve, int requestedSeats)
{
this.reserve = reserve;
this.requestedSeats = requestedSeats;
}
@Override
public void run() // LINE C
{
reserve.reserveSeat(requestedSeats);
}
}
OUTPUTThread-0 entered.
Availableseats : 10 Requestedsetas : 5
Seat Available. Reserve now :-)
5 seats reserved.
Thread-0 leaving.
----------------------------------------------
Thread-2 entered.
Availableseats : 5 Requestedsetas : 2
Seat Available. Reserve now :-)
2 seats reserved.
Thread-2 leaving.
----------------------------------------------
Thread-1 entered.
Availableseats : 3 Requestedsetas : 4
Requested seats not available :-(
Thread-1 leaving.
----------------------------------------------
DESCRIPTIONIn the above program we have three classes SeatReservation
, Reservation
and Person
. In SeatReservation
at LINE A
we have an object for Reservation
. At LINE B
we are creating three threads and passing the Reservation
reference as a parameter and running them by invoking thread's start
method which in turn invokes Persons run
method. Remember all the threads function on the same Reservation object. At LINE C
in the Person
class run method we are invoking reserveSeat
method of Reservation
. At LINE D
we made the reseveSeat
method as synchronized
meaning only one thread can access it at a time. At LINE E
we are making the thread to sleep for 100 milliseconds.
THINGS TO TRY
- Create one more thread for
Person
with requested seats 1 and see the output.
- Remove the
synchronized
key word for the method reserveSeat
in Reservation
.
Note : Remember there is no guarantee on which threads runs first so the output may differ each time when we run the program.