Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I try to avoid static synchronized method

Tags:

java

From what I've understood the following code is not efficient:

class Foo {
    static Resource resource1;
    static Resource resource2;

    static synchronized void methodA() {
       resource1.add("abc");
    }

    static synchronized void methodB() {
       resource2.add("abc");
    }
}

From what I've understood, both methods lock in a single object (the class object Foo.class), so I'm guessing the following is a good optimization?

class Foo {
    static Resource resource1;
    static Resource resource2;

    static void methodA()  {
       synchronized(resource1) {
           resource1.add("abc");
       }
    }

    static void methodB()  {
       synchronized(resource2) {
           resource2.add("123");
       }
    }
}

As long as the two resources do not depend on each other.

When should I consider using static synchronized method?

like image 207
Gam Avatar asked Apr 21 '16 11:04

Gam


2 Answers

Use the static synchronized construct when your class abstracts access to a single critical resource, thus locking on the class is semantically correct.

If your class abstracts access to more than one critical resource, then you have to use finer locking, as in your example.

You can consider the synchronized modifier for methods as syntactic sugar, there is no extra black magic other than locking on the class (or the instance if the method wasn't static).

In your first example, it's questionable why a single class is providing access to two different critical resources if they are totally unrelated. Perhaps you could move the critical sections to the Resource classes themselves.

like image 56
jjmontes Avatar answered Sep 21 '22 23:09

jjmontes


Your optimization is right.

The first code lock on the Foo.class

The second code lock on two different objects: resource1 and resource2.

Visually you can imagine this

First code:

 Thread 1              Thread 2
 ------------------------------

 Foo.methodA()

                        Foo.methodB()   
 // A call to methodB needs to wait for completion of methodA

Second code:

 Thread 1              Thread 2
 ------------------------------

 Foo.methodA()         Foo.methodB()    
 // At the same time in a machine with at least a dual core

You should consider to use a static synchronized method only when you have one resource to synchronize.

like image 35
Davide Lorenzo MARINO Avatar answered Sep 20 '22 23:09

Davide Lorenzo MARINO