解锁后的Java线程执行顺序

时间:2011-06-11 18:01:09

标签: java multithreading locking monitor

假设我有2个线程, t1 t2 ,以及一个锁定对象 m 。线程 t1 处于无限循环中,在每次迭代时,它会抓取 m 上的锁定,执行一些操作,解锁 m 并重新开始立即。在一次迭代中, t2 请求锁定 m 但被 t1 阻止并且必须等待。现在,当 t1 解锁 m 时,是否可以保证 t2 将获得 m 的下一个锁?或者 t1 可以在下一次迭代中潜行吗?

通常,是否为等待线程设置了队列?如果 t1 具有锁定,并且所有其他线程也希望锁定按以下顺序被阻止: t2 t3 ,...,其余的线程是否会按照它们被阻止的顺序继续执行(例如 t2 运行,然后 t3 等)?

(我简要地仔细阅读了java规范并找不到答案。如果它在那里,请告诉我,我会回去仔细阅读。)

谢谢! (首先是SO帖子,哇哦!)

4 个答案:

答案 0 :(得分:2)

是的,有一个队列,这可能是公平的。公平队列更昂贵,非公平更快(赢得CAS赢得锁定)。 查看java.util.concurrent.locks.AbstractQueuedSynchronizer了解更多信息。

  

剩下的线程会继续吗?   按照他们的顺序执行   被阻止(例如t2运行,然后是t3等)?

主要问题是它们是同时/同时执行的,您无法真正定义同时执行的2个事件的顺序。但是w / fair(由于额外的成本而未经推荐)锁定任何设法为锁定登记的线程将最终获得拥有它。

答案 1 :(得分:0)

不,没有这样的保证。您可以建议Java为ReentrantLock objects to be fair,但这是建议性的,不保证任何订单。

一般情况下,你不能(没有显式同步来实现它)保证这样的顺序,因为 t2 在它甚至获得线程之前可能已被中断,并且它完全取决于操作系统来决定哪个线程在恢复时恢复。

答案 2 :(得分:0)

对大多数用途都没有保证。您会注意到一些java.util.concurrent抽象提供了“公平锁定”的选项 - 它或多或少地保证每个等待锁的线程最终都会被调用(不是特定的顺序)。没有公平,就没有保证。 OTOH,公平是非常昂贵的。 (参见Java Concurrency In Practice中的一些基准测试),通常,概率可能性足够好。

答案 3 :(得分:0)

您可以使用公平Semaphore来保证订单。标准的内置Java锁/监视器不公平,不能以公平的方式排序。

Semaphore sem = new Semaphore(1, true);

//usage:
sem.acquire();
try {
  //holding a lock
  //of course both threads share the same semaphore
} finally {
  sem.release();
}

理论上,锁定释放后,T1可以在下一次迭代中再次锁定,尽管T2已经等待它。不太可能,但可能。

相关问题