我已经阅读了有关同步方法的Oracle Doc,以及它们如何将锁定到多线程程序中,但是我有一件事不清楚。随后的调用已经锁定的方法排队了吗?
可以说我们有一个课程:
class Astore {
...
public synchronized void a() {
doSomethingTimeConsuming();
}
...
}
和3个呼叫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();
我不确定我是否正确地进行了示例,但是重点是,几乎同时使用同步方法对同一对象进行了调用。
操作顺序会存储在队列中,以使线程调用为:
- t1(被称为首先)
- T2(在T1之后被称为)
- T3
- t1再次(在其他线程请求方法时,它已经忙于做某事)
我可以安全地假设这将是行为,或者不能保证这将是订单(或更糟糕的是,T2和T3可能会随机调用)
当多个线程可能需要共享数据时,最佳实践是什么(例如,每个活动连接都有一个线程的套接字服务器 - 我不希望6个客户在等待第一个端的一个时间来完成一个巨大的时间上传到共享数据结构)
no,它不会排队呼叫该方法。
如果呼叫是由已经有锁定的线程(例如,递归电话)的线程,那么它将像正常人一样进行。
其他试图使锁定能够打电话的线程将在那里保存并等到锁定。
。不能保证订单,如果这很重要,请使用 fair reentrantlock。
如果使用reneterantlock而不是同步块,则可以设置一个公平参数,以便等待大多数线程在另一个线程释放锁定时获得锁定,您可以阅读这里更多
folkol是正确的。
实际上它取决于机器的设计(CPU)
呼叫者应等到CPU分配资源为止。然后,CPU随机选择下一个呼叫者之一,并为其分配资源并锁定(由于同步),直到第二个呼叫者完成其作业为止。