Problem with running static and non-static synchronized methods at the same time?

In the following example

  • What happens if different threads try to access static and non-static synchronized methods at the same time and, in turn, change the static data using two methods?
  • Are there problems using the do-while loop of the run () method to create a new object of the BadDesign class for each non-static call to the synchronized method?
  • Is this Java code correctly synchronized or not?

Here is a sample code illustrating my questions:

BadDesign.java

public final class BadDesign{ private static int sensitiveData; public synchronized static void changeDataViaStaticMethod(int a){ //... updating the sensitiveData sensitiveData = a; } public synchronized void changeDataViaNonStaticMethod(int b){ //... updating the sensitiveData sensitiveData = b; } public static void showSensitiveDataStatic(){ System.out.println("Static: " + Thread.currentThread().getName()+ " - " + sensitiveData); } public void showSensitiveData(){ System.out.println(Thread.currentThread().getName() + " - " + sensitiveData); } public static void main(String[] args){ new Thread(new TestThread11()).start(); new Thread(new TestThread11()).start(); } } 

And TestThread11.java

 class TestThread11 implements Runnable{ public void run(){ int i = 0; do{ BadDesign.changeDataViaStaticMethod(5); BadDesign.showSensitiveDataStatic(); //... new object for every iteration //... so synchronization of non-static method //... doesn't really do anything significant here BadDesign bd = new BadDesign(); bd.changeDataViaNonStaticMethod(10); bd.showSensitiveData(); }while (i++ < 100); } } 
+4
source share
3 answers
  • Static and non-static data accessed by several threads are processed by different levels of locks. Threads that access non-stationary methods share an object-level lock (which for each object), where access to static methods requires a class-level lock (which is 1 for each class).
  • There is no problem with the do-while loop since

      BadDesign.changeDataViaStaticMethod(5); //needs BadDesign Class lock. BadDesign.showSensitiveDataStatic(); //does not need any lock 

and

  bd.changeDataViaNonStaticMethod(10); // needs lock for bd object. bd.showSensitiveData(); //does not need any lock 

I hope the answers to your questions.

+2
source

The non-static version will allow two different threads to connect through different objects, acquire different locks and still access the same shared data. Essentially, this is not thread safe, and basically makes locks useless. You want any part of the shared data to be locked with one lock.

You can still use non-static methods if you really want to (for example, if the result should also be determined by the instance data), but you should access the shared data using a shared lock, for example

 private static final Object staticLock = new Object(); ... synchronized (staticLock) { // Read or write static data } 
+6
source

I guess this is some kind of term paper. It seems that in this particular problem it is worth highlighting the two fundamental foundations of Java

  • Any object can serve as a monitor in Java
  • How synchronized implicitly uses the current instance of an object as lock

Paragraph 1 talks a lot about understanding what a monitor is. I invite you to study the relevant section of the Java language specification, Threads and Locks . A monitor is what a thread can lock and unlock . When one thread blocks it, any other thread trying to block this particular monitor will wait (block) until the first thread unlocks it.

Point 2 is dedicated to the compiler function in Java. When you specify something as synchronized , without explicitly specifying which monitor to use, Java will use the instance of the called object. If, however, the method is static, it will use an instance of class objects ( java.lang.Class ) as a monitor. What does this really mean? Since there is only one unique global instance of each class object in the context of the loader class, the static method will have only one monitor. In contrast, an instance method will use an instance of an object that is called as a monitor, so each object will have its own monitor. Static methods are synchronized globally, the instance method is synchronized for each specific instance of the class.

+1
source

All Articles