3
votes

I really don't understand what purpose of multiple-level synchronized statement? For instance, in the code:

static void m() throws Exception {
    synchronized (sync) {
        System.err.println("First level synchronized");
        synchronized (sync) {
            System.err.println("Second level synchronized");
            synchronized (sync) {
                System.err.println("Third level synchronized");
            }
        }
    }
}

public static void main(String[] args) throws Exception {
    Runnable r = new Runnable() {
        @Override
        public void run() {
            try {
                m();
            } catch (Exception ex) {
                Logger.getLogger(IO.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    };
    Thread th1 = new Thread(r);
    Thread th2 = new Thread(r);
    th1.run();
    th2.run();
}

It is impossible to execute the most-enclosing synchronized statement for any thread if some thread has already started to execute one. So, I cannot see any usefulness of such construction. Could you provide an example to understand such using?

An other example of nested synchronized statements can be found in the official JLS specs: http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.19

2
I cannot see any usefulness either (unless of course 3 different objects are used as locks instead of a single one). Where have you seen such code? - JB Nizet
Are you sure the blocks where synchronized on the same object? - Boris the Spider
I cannot provide such example since this seems really odd. - Luiggi Mendoza
@JBNizet It is a bit modification of the code from the JLS, section 14.19. - user2953119
Ah, but the JLS explains what happens when such code is used. It doesn't say it's a good idea to use such code. That said, it's quite frequent to have synchronized methods call other synchronized methods (because the called one could also be called directly). The JLS explains what happens when a single thread synchronizes several times on the same object. - JB Nizet

2 Answers

7
votes

From the OP's comments this comes from the JLS ยง14.19

class Test {
    public static void main(String[] args) {
        Test t = new Test();
        synchronized(t) {
            synchronized(t) {
                System.out.println("made it!");
            }
        }
    }
}

The JLS goes on to say:

Note that this program would deadlock if a single thread were not permitted to lock a monitor more than once.

This is example is meant to illustrate that synchronized blocks are reentrant.

This JLS is not a document of useful coding practices.

It is desgined to illustrate how the language is supposed to work. It documents language constructs and defines their behaviour - it is a specification.

2
votes

It's an example of something that is legal, not something that is useful or recommended. It's showing that the lock is recursive ("Note that this program would deadlock if a single thread were not permitted to lock a monitor more than once").