Limitations of synchronization and the uses of static synchronization in multithreading
Multithreading feature of java is the feature around which the concept revolves as it allows concurrent execution of two or more parts of a program for maximum utilization of CPU. Each part of such a program is called a thread. So, threads are lightweight processes within a process where as we all know threads can be created by using two mechanisms as listed:
- Extending the Thread class
- Implementing the Runnable Interface
If multiple threads access a single resource at a time then there exists a possibility of data racing or bad output. Let us understand this with the help of a story. Let us take the example of data racing in multithreading to perceive the limitations of synchronization and the uses of static synchronization. Let us lick off directly with the data racing in multithreading.
Implementation:
Shubham and Sharmistha was planning a date and tried to book movie tickets. Unfortunately, only 1 ticket was available. Shubham who was a genius Java programmer knew a trick and requested 1 ticket simultaneously for both of them at the same time. The naive ticket booking system assigned 2 threads and passed them through the book method. In the end of the procedure, both of them got 1 ticket each and the number of tickets left was -1!
Illustration: Data racing in multithreading
Java
class book {
int tickets = 1 ;
void book( int request, String name)
{
if (tickets >= request) {
System.out.println(name + " booked " + request
+ " ticket." );
tickets = tickets - 1 ;
System.out.println( "Tickets left: " + tickets);
}
else {
System.out.println( "No tickets are available." );
}
}
}
class myThread extends Thread {
book obj;
int n;
String name;
myThread(book obj, String name, int n)
{
this .obj = obj;
this .n = n;
this .name = name;
}
public void run() { obj.book(n, name); }
}
public class GFG {
public static void main(String[] args)
{
book obj = new book();
myThread t1 = new myThread(obj, "Shubham" , 1 );
myThread t2 = new myThread(obj, "Sharmistha" , 1 );
t1.start();
t2.start();
}
}
|
Output-
Shubham booked 1 ticket.
Sharmistha booked 1 ticket.
Tickets left: 0
Tickets left: -1
Number of tickets can not be negative. To handle this problem engineers came up with the synchronization concept.
Synchronization- we provide a lock to the object and declare a sensitive area(withdraw method). An object can have multiple threads but the sensitive area can only be accessed by 1 thread at a time.
Illustration: Handling data racing due to multithreading using synchronization.
Java
class book {
int tickets = 1 ;
synchronized void book( int request, String name)
{
if (tickets >= request) {
System.out.println(name + " booked " + request
+ " ticket." );
tickets = tickets - 1 ;
System.out.println( "Tickets left: " + tickets);
}
else {
System.out.println( "No tickets are available." );
}
}
}
class myThread extends Thread {
book obj;
int n;
String name;
myThread(book obj, String name, int n)
{
this .obj = obj;
this .n = n;
this .name = name;
}
public void run() { obj.book(n, name); }
}
public class GFG {
public static void main(String[] args)
{
book obj = new book();
myThread t1 = new myThread(obj, "Shubham" , 1 );
myThread t2 = new myThread(obj, "Sharmistha" , 1 );
t1.start();
t2.start();
}
}
|
Output-
Shubham booked 1 ticket.
Tickets left: 0
No tickets are available.
Limitations of synchronization:
If we have multiple thread from 1 object than synchronization will handle the data racing or bad output. What will happen if multiple threads are assigned from multiple objects? this will again result in bad output or data racing.
Illustration: Cons of synchronization when multiple threads gets assigned from multiple objects.
Java
class book {
static int tickets = 1 ;
synchronized void book( int request, String name)
{
if (tickets >= request) {
System.out.println(name + " booked " + request
+ " ticket." );
tickets = tickets - 1 ;
System.out.println( "Tickets left: " + tickets);
}
else {
System.out.println( "No tickets are available." );
}
}
}
class myThread extends Thread {
book obj;
int n;
String name;
myThread(book obj, String name, int n)
{
this .obj = obj;
this .n = n;
this .name = name;
}
public void run() { obj.book(n, name); }
}
public class GFG {
public static void main(String[] args)
{
book obj = new book();
book obj2 = new book();
myThread t1 = new myThread(obj, "Shubham" , 1 );
myThread t2 = new myThread(obj2, "Sharmistha" , 1 );
t1.start();
t2.start();
}
}
|
Output-
Sharmistha booked 1 ticket.
Shubham booked 1 ticket.
Tickets left: 0
Tickets left: -1
We have only 1 ticket but due to data racing both of them booked successfully! To handle this problem we need to study static synchronization.
Static Synchronization- Say we have 5 objects. Each objects have multiple threads. Now the sensitive area will be accessed by 5 threads at a time!
To handle this problem engineers came up with the idea of Static synchronization. We provide a lock to the class. The class will select 1 object at a time. The object in turn will choose 1 thread and pass it through the sensitive area.
Illustration: Handling data racing using static synchronization.
Java
class book {
static int tickets = 1 ;
static synchronized void book( int request, String name)
{
if (tickets >= request) {
System.out.println(name + " booked " + request
+ " ticket." );
tickets = tickets - 1 ;
System.out.println( "Tickets left: " + tickets);
}
else {
System.out.println(
name + ", No tickets are available." );
}
}
}
class myThread extends Thread {
book obj;
int n;
String name;
myThread(book obj, String name, int n)
{
this .obj = obj;
this .n = n;
this .name = name;
}
public void run() { obj.book(n, name); }
}
public class GFG {
public static void main(String[] args)
{
book obj = new book();
book obj2 = new book();
myThread t1 = new myThread(obj, "Shubham" , 1 );
myThread t2 = new myThread(obj2, "Sharmistha" , 1 );
t1.start();
t2.start();
}
}
|
Output-
Shubham booked 1 ticket.
Tickets left: 0
Sharmistha, No tickets are available.
Using static synchronization, we have prepared a system to prevent illegal ticket booking.
Conclusion-
- When we have multiple threads from a single object than we can use synchronization to lock the object to pass 1 thread at a time and prevent bad output.
- If multiple threads are assigned from multiple objects than we can not use synchronization. In such cases providing lock to the object will result in data racing. we need to use static synchronization and provide lock to the class. The class will select 1 object at a time. The object in turn will choose 1 thread and pass it to the sensitive area.
Last Updated :
24 May, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...