Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

do synchronized java methods queue calls?

I've read the oracle doc about synchronized methods and how they may introduce a lock to the multithreaded program, but there is one thing that is unclear to me. Are the subsequent calls to an already locked methods queued?

Lets say we have a class:

class Astore {
    ...
    public synchronized void a() {
        doSomethingTimeConsuming();
    }
    ...
}

and 3 threads that call astore.a()

final Astore astore = new Astore();

Thread t1 = new Thread(new Runnable() {
    public void run() { 
        astore.a();
        doSomethingElse();
        astore.a();
    }
});
t1.start();

Thread t2 = new Thread(new Runnable() {
    public void run() {
        astore.a();
    }
});
t2.start();

Thread t3 = new Thread(new Runnable() {
    public void run() {
        astore.a();
    }
});
t3.start();

I'm not sure if I've made the example correctly, but the point is, that 3 threads make a call to the same object with synchronized method almost at the same time.

Will the order of operations be stored in a queue so that the threads invoking will be:

  1. t1 (as it was called first)
  2. t2 (was called after T1)
  3. t3
  4. t1 again (it was busy doing something with A already while other threads requested method)

Can I safely assume that will be the behavior, or there is no guarantee that this will be the order (or even worse, t2 and t3 might get called in random order)

What is the best practice when multiple threads may need to share data (for instance a socket server with one thread for each active connection - I don't want 6 clients to time out while waiting for the first one to finish a huge upload to a shared data structure)

like image 723
user3002166 Avatar asked May 20 '15 10:05

user3002166


2 Answers

No, it will not queue calls to the method.

If the call is made from a Thread that already has got the lock (a recursive call, for example), then it will just proceed like normal.

Other threads that attempt to get the lock to be able to make a call will hold there and wait until the lock is released.

The order is not guaranteed, use a fair ReentrantLock if that is important.

like image 143
folkol Avatar answered Sep 21 '22 10:09

folkol


If you use ReneterantLock instead of synchronized block there is a fairness parameter that you can set so that the thread that is waiting most gets the lock when lock is released by another thread, You can read more here

like image 34
Sunil Rajashekar Avatar answered Sep 23 '22 10:09

Sunil Rajashekar