do synchronized java methods queue calls?

亡梦爱人 提交于 2020-01-03 15:36:01

问题


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)


回答1:


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.




回答2:


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




回答3:


folkol is correct.

Actually its depends on the machine's design (CPU)

The callers should wait until the resource got allocated by the CPU. The CPU then randomly choose one of the next caller and allocate the resource for it and lock it (Because of synchroize) until the second caller finishes its job.



来源:https://stackoverflow.com/questions/30346882/do-synchronized-java-methods-queue-calls

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!