Can we synchronize static method in java

Tech Tutorials

Tutorials and posts about Java, Spring, Hadoop and many more. Java code examples and interview questions. Spring code examples.

Thursday, July 8, 2021

Static Synchronization in Java Multi-Threading

With instance method synchronization, threads are executed one thread per instance. That may create problems when we have more than one instance of the same class. In that scenario you may have to synchronize at the class level if you want to have a single lock for all the instances of the class rather than synchronizing at object level. That is what static synchronization in Java does.

  • static synchronized method
  • An enclosed synchronized code block with in a static method.

Synchronized static method in Java

Synchronized instance method is synchronized on the instance(object) of the class. If a class has two objects, then two threads can acquire lock on these two objects and enter the synchronized method or block at the same time.

Synchronized static method Java example

Here we have a class Message whose object will be shared among threads. In class Message there is a method displayMsg. You want one thread to finish printing the message with in the method then only another thread should start executing the method. Here two objects of Message1 class, msg1 and msg2 are created. Then four threads are created out of which two threads share the msg1 object where as the other two share the msg2 object.

Читайте также:  Java unit test controller

First let’s see with the help of an example what problem we may face in case we don’t use static synchronization.

Code without static synchronization

//This class' shared object will be accessed by threads class Message1 < public synchronized void displayMsg()< System.out.println("In run method " + Thread.currentThread().getName()); for(int i = 0; i < 5 ; i++)< System.out.println(Thread.currentThread().getName() + " i - " + i); try < Thread.sleep(50); >catch (InterruptedException e) < // TODO Auto-generated catch block e.printStackTrace(); >> > > class MyClass1 implements Runnable < Thread t; Message1 msg; MyClass1(Message1 msg)< this.msg = msg; t = new Thread(this); t.start(); >@Override public void run() < msg.displayMsg(); >> public class SynchronizedDemo1 < public static void main(String[] args) < Message1 msg1 = new Message1(); Message1 msg2 = new Message1(); // Two threads on msg1 object MyClass1 mc1 = new MyClass1(msg1); MyClass1 mc2 = new MyClass1(msg1); // Two threads on msg2 object MyClass1 mc3 = new MyClass1(msg2); MyClass1 mc4 = new MyClass1(msg2); >>
In run method Thread-1 Thread-1 i - 0 In run method Thread-3 Thread-3 i - 0 Thread-3 i - 1 Thread-1 i - 1 Thread-3 i - 2 Thread-1 i - 2 Thread-1 i - 3 Thread-3 i - 3 Thread-3 i - 4 Thread-1 i - 4 In run method Thread-2 Thread-2 i - 0 In run method Thread-0 Thread-0 i - 0 Thread-0 i - 1 Thread-2 i - 1 Thread-0 i - 2 Thread-2 i - 2 Thread-2 i - 3 Thread-0 i - 3 Thread-0 i - 4 Thread-2 i - 4

Here it can be seen that thread-0 and thread-1 are invoked on msg1 object where as thread-2 and thread-3 are invoked on msg-2 object.

As we already know if you are using synchronization on the instance methods then the thread will have exclusive lock one per instance. In the given example two of the threads share one object and another two share another object thus thread-0 and thread-1 will be synchronized using one monitor and thread-2 and thread-3 are synchronized using another monitor.

We can see in the output thread-0 and thread-1 are not having any thread interference same way thread 2 and thread-3 are not having any thread interference but thread-1 and thread-3 are entering the synchronized method at the same time with their own respective locks. Lock hold by thread-1 will stop thread-0 from entering the synchronized method as they are working on the same instance. But it cannot stop thread-2 or thread-3 as they are working on another instance.

Code with static synchronized method

In these kinds of scenarios if we still want that a synchronized method or block is accessed by a single thread then we have to use static synchronized method or block to have synchronization at the class level rather than on the instance level.

As we know that every class loaded by the JVM is essentially an object of type Class. So, in that case too, monitor of the object is acquired but that is the monitor of the Class object that represents the class to which the static method belongs.

We just need to change the displayMsg() method to make it a static method-

//This class' shared object will be accessed by threads class Message1 < public static synchronized void displayMsg()< System.out.println("In run method " + Thread.currentThread().getName()); for(int i = 0; i < 5 ; i++)< System.out.println(Thread.currentThread().getName() + " i - " + i); try < Thread.sleep(50); >catch (InterruptedException e) < e.printStackTrace(); >> > >
In run method Thread-0 Thread-0 i - 0 Thread-0 i - 1 Thread-0 i - 2 Thread-0 i - 3 Thread-0 i - 4 In run method Thread-2 Thread-2 i - 0 Thread-2 i - 1 Thread-2 i - 2 Thread-2 i - 3 Thread-2 i - 4 In run method Thread-3 Thread-3 i - 0 Thread-3 i - 1 Thread-3 i - 2 Thread-3 i - 3 Thread-3 i - 4 In run method Thread-1 Thread-1 i - 0 Thread-1 i - 1 Thread-1 i - 2 Thread-1 i - 3 Thread-1 i - 4

It can be seen now how threads are executing one after another with any one thread holding the lock while it is executing.

static synchronized block in Java

Same way we can have static synchronized block where we need to synchronize the class object itself.

Java static synchronized block syntax

Synchronized(CLASS_NAME.class)

static synchronized block Java example

If we take the previous example itself and make it a static synchronized block instead of static synchronized method then Message1 class will look like

//This class' shared object will be accessed by threads class Message1 < public static void displayMsg()< System.out.println("In run method " + Thread.currentThread().getName()); synchronized(Message1.class)< for(int i = 0; i < 5 ; i++)< System.out.println(Thread.currentThread().getName() + " i - " + i); try < Thread.sleep(50); >catch (InterruptedException e) < e.printStackTrace(); >> > > >
In run method Thread-0 In run method Thread-3 Thread-0 i - 0 In run method Thread-1 In run method Thread-2 Thread-0 i - 1 Thread-0 i - 2 Thread-0 i - 3 Thread-0 i - 4 Thread-2 i - 0 Thread-2 i - 1 Thread-2 i - 2 Thread-2 i - 3 Thread-2 i - 4 Thread-1 i - 0 Thread-1 i - 1 Thread-1 i - 2 Thread-1 i - 3 Thread-1 i - 4 Thread-3 i - 0 Thread-3 i - 1 Thread-3 i - 2 Thread-3 i - 3 Thread-3 i - 4

See how the first statement is printed for all the threads as that statement is outside the synchronized block. But only thread-0 acquires the lock and starts its execution, all the other threads are suspended till the execution of thread-0 finishes.

That’s all for this topic Static Synchronization in Java Multi-Threading. If you have any doubt or any suggestions to make please drop a comment. Thanks!

Источник

Synchronized Method in Java | Example Program

Scientech Easy

When we declare a synchronized keyword in the header of a method, it is called synchronized method in Java.

Using the synchronized keyword, we can synchronize all the methods of any class.

When a method is declared as synchronized, JVM creates a monitor (lock). To enter the monitor, the synchronized method is called. The thread that calls the synchronized method first, acquires object lock.

If the object lock is not available, the calling thread is blocked and it has to wait until the lock becomes available.

As long as thread holds lock (monitor), no other thread can enter the synchronized method and will have to wait for the current thread to release the lock on the same object. Look at the below figure to understand better.

Synchronized method in Java

Once a thread completes the execution of code inside the synchronized method, it releases object lock and allows other thread waiting for this lock to proceed.

That is once a thread completes its work using synchronized method, it will hand over to the next thread that is ready to use the same resource.

Syntax to declare Synchronized method in Java

The general syntax to make a method synchronized is as follows:

synchronized data_type method_name() < // Code to be synchronized. >

For example, if you want to synchronize the code of show() method, add the synchronize before the method name.

Since the code inside the method is synchronized, the code will not be available to more than one thread at a time.

public class Table < void printTable(int n) // Here, method is not synchronized. < for(int i = 1; i catch(InterruptedException ie) < System.out.println(ie); >>> > public class Thread1 extends Thread < Table t; // Declaration of variable t of class type Table. // Declare one parameterized constructor and pass variable t as a parameter. Thread1(Table t) < this.t = t; >public void run() < t.printTable(2); >> public class Thread2 extends Thread < Table t; Thread2(Table t) < this.t = t; >public void run() < t.printTable(10); >> public class UnsynchronizedMethod < public static void main(String[] args) < // Create an object of class Table. Table obj = new Table(); Thread1 t1 = new Thread1(obj); Thread2 t2 = new Thread2(obj); t1.start(); t2.start(); >>
Output: 2 10 4 20 30 6 40 8 50 10

Explanation:

1. The class Table has a method named printTable() which takes a parameter n of Integer type. This method will print the table of 2 and 10. The sleep() method is called inside the printTable() method that causes the current thread to halt for 0.4 sec.

2. The constructor of class Thread1 takes one argument as a reference to an object of class Table.

3. When the first thread starts, run() method is called for execution. The run() method calls printTable() method on the object t of class Table.

4. When the sleep() method is called on the first thread, it pauses thread for 0.4 sec before complete its execution. Meanwhile, thread scheduler switches to the second thread for execution.

Thus, the output of program is in mixed up form and does not get expected results. This is because two threads call the same method printTable() and switch from one thread to another thread without completion of its tasks.

Now let’s modify program 1 where we will declare synchronized keyword before the signature of printTbale() method.

This technique will allow only one thread to access printTable() method to complete its task at a time and prevent another thread to access it.

Thus, we will get the correct output. Look at the following source code to understand better.

Program code 2:

public class Table < synchronized void printTable(int n) // Here, method is synchronized. < for(int i = 1; i catch(InterruptedException ie) < System.out.println(ie); >>> > public class Thread1 extends Thread < Table t; // Declaration of variable t of class type Table. // Declare one parameterized constructor and pass variable t as a parameter. Thread1(Table t) < this.t = t; >public void run() < t.printTable(2); >> public class Thread2 extends Thread < Table t; Thread2(Table t) < this.t = t; >public void run() < t.printTable(10); >> public class SynchronizedMethod < public static void main(String[] args) < // Create an object of class Table. Table obj = new Table(); Thread1 t1 = new Thread1(obj); Thread2 t2 = new Thread2(obj); t1.start(); t2.start(); >>
Output: 2 4 6 8 10 10 20 30 40 50

Explanation:

As you can see in the output, we get the expected output. This is because once the first thread enters into synchronized printTable() method on an instance, the second thread can not enter into synchronized printTable() method on the same instance.

Thus, once the first thread completes its task, then second thread enters into synchronized method to complete its task.

Simultaneous execution of synchronized methods is possible for two different objects of the same class. Let’s take an example program based on it.

Program code 3:

public class Table < synchronized void printTable1(int x) // First synchronized method. < for(int i = 1; i catch(InterruptedException ie) < System.out.println(ie); >> > synchronized void printTable2(int y) // Second synchronized method. < for(int j = 1; j catch(InterruptedException ie) < System.out.println(ie); >> > > public class Thread1 extends Thread < Table t; // Declaration of variable t of class type Table. Thread1(Table t) < this.t = t; >public void run() < t.printTable1(2); // Calling first synchronized method. >> public class Thread2 extends Thread < Table t; Thread2(Table t) < this.t = t; >public void run() < t.printTable2(10); // Calling second synchronized method. >> public class SynchronizedMethod < public static void main(String[] args) < // Create two objects of class Table. Table obj = new Table(); Table obj2 = new Table(); Thread1 t1 = new Thread1(obj); Thread2 t2 = new Thread2(obj2); t1.start(); t2.start(); >>

As you can observe the output, simultaneous execution of two synchronized methods has happened with two different instances of the same class.

Can we synchronize static method in Java?

Yes, a static method can also be synchronized. In this case, the lock is placed on the class, not on the object. The thread will execute the method body only when the lock is placed on the class.

It will hold the lock until it leaves the method body. This is called static synchronization in java.

Let’s take an example program based on it to understand better.

Program code 4:

public class Table < synchronized static void printTable(int x) // Here, static method is synchronized. < for(int i = 1; i catch(InterruptedException ie) < System.out.println(ie); >> > > public class Thread1 extends Thread < public void run() < Table.printTable(2); // Calling synchronized static method using class name with passing argument 2. >> public class Thread2 extends Thread < public void run() < Table.printTable(10); // Calling synchronized static method using class name with passing argument 10. >> public class SynchronizedMethod < public static void main(String[] args) < Thread1 t1 = new Thread1(); Thread2 t2 = new Thread2(); t1.start(); t2.start(); >>

Hope that this tutorial has covered synchronized method in Java with example programs. I hope that you will have understood the basic concepts of the Synchronized method.

In the next tutorial, we will learn synchronized block in Java with example programs. If you get any incorrect in this tutorial, please inform to our team through email. Your email will be precious to us.
Thanks for reading.
Next ⇒ Deadlock in Java ⇐ PrevNext ⇒

Источник

Оцените статью