idementia idementia - 3 months ago 21
Java Question

order of calling synchronized methods

i believe, this is a simple question, but still, i don't get it on my own. Say, i have following code.

Runnable objectRunnable = new Runnable() {
void run() {
synchronized(object) {
for (int i = 0; i < 5; i++) {
System.out.println("it's runnable");
Thread.sleep(100);
}
}
}
};

void doSomething() {
synchronized(object) {
for (int i = 0; i < 5; i++) {
System.out.println("it's doSomething");
Thread.sleep(100);
}
}
}

synchronized (object) {
new Thread(objectRunnable).start();
}
object.doSomething();


So, the output is like

it's doSomething
it's doSomething
it's doSomething
it's doSomething
it's doSomething
it's runnable
it's runnable
it's runnable
it's runnable
it's runnable


Question is why
doSomething()
goes before thread? Moreover, if i put multiple calls of object methods after synchro block, they all be called subsequently, and only then program returns to the content of thread. If i replace that thread calling line in synchro block with, say, calling some analog object method, than everything is ok, and goes in specified order.

Do methods of synchronized object itself have some kind of priority in execution before any threads, synchronized on this object?

Answer

What you have here is a race condition: your runnable gets blocked waiting on a monitor upon starting up due to synchronized (object) around its creation. Once the thread creating runnable releases the monitor, the newly created thread with runnable does not get a chance to grab it, because the same thread re-enters it again in the doSomething() method.

If you add a call to Thread.sleep(100); before calling object.doSomething()

synchronized (object) {
    new Thread(objectRunnable).start();
}
Thread.sleep(100); // <<== Add this line
object.doSomething();

the order of printouts will reverse (demo).

it's runnable
it's runnable
it's runnable
it's runnable
it's runnable
it's doSomething
it's doSomething
it's doSomething
it's doSomething
it's doSomething