Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem with concurrent execution of static and non-static synchronized methods?

Tags:

java

In the following example

  1. What will happen if different threads try to access the static and non-static synchronized methods concurrently, and in turn try to change the static data using the two methods?
  2. Is there any problems using do-while loop of the run() method to create a new object of the class BadDesign for every non-static synchronized method call?
  3. Is this Java code properly synchronized or not?

Here is the 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);
    }
}
like image 806
divz Avatar asked Jan 20 '23 02:01

divz


2 Answers

The non-static version will allow two different threads to come in via different objects, acquire different locks and still access the same shared data. Fundamentally, that's not thread-safe, and basically makes the locks useless. You want any piece of shared data to be covered by one lock.

You can still use non-static methods if you really want to (e.g. if the result should be determined partly by instance data as well) but you should access the shared data via a shared lock, e.g.

private static final Object staticLock = new Object();

...

synchronized (staticLock)
{
    // Read or write static data
}
like image 104
Jon Skeet Avatar answered May 02 '23 03:05

Jon Skeet


  1. The static and non-static data accessed by multiple threads are handled by different level of locks. The threads which access the non-static methods share object level lock(which is per object) where as to access static methods you need class level lock(which is 1 per Class)
  2. There is no problem with the do-while loop, as

       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 that answers your questions.

like image 37
Swagatika Avatar answered May 02 '23 02:05

Swagatika