我有 10 个线程,每个线程都有自己的 ID,从 1 到 10;所有线程都有 2 个阶段要做(即 Phase1 和 Phase2)。我试图让所有线程首先完成它们的 Phase1,在任何线程进入 Phase2 之前,使用信号量(我做到了并且效果很好),但是我应该让所有 10 个线程按照它们的 TID(线程 ID)的顺序开始。我尝试了很多方法,但没有得到结果!我得到的最终结果仅适用于前 4 个线程(有时是 5 或 6 个),然后其余线程出现顺序混乱!
这些是我创建的信号量:
...private static Semaphore mutex = new Semaphore(1);
// s1 is to make sure phase I for all is done before any phase II begins
private static Semaphore s1 = new Semaphore(0);
// s2 is for use in conjunction with Thread.turnTestAndSet() for phase II proceed in the thread creation order
private static Semaphore s2 = new Semaphore(1);
private static int n=10;
private static int count = 0;
这是我的线程方法:
static class AcquireBlock extends BaseThread
{
public void run()
{
mutex.P();
phase1();
count++;
mutex.V();
if (count == n)
{
s1.V();
}
s1.P();
s1.V();
while(!this.turnTestAndSet());
s2.P();
phase2();
s2.V();
}
} // class AcquireBlock
turnTestAndSet 方法如下:
public synchronized boolean turnTestAndSet()
{
if(siTurn == this.iTID)
{
siTurn++;
return true;
}
return false;
}
其中 siTurn 初始化为 1。
我在代码中遇到的问题(我认为)是,当一个线程到达 While 循环 [while(!this.turnTestAndSet())] 时,它可能会成功跳过循环(如果成功),但另一个线程可能会在前一个线程进入阶段 2 之前启动并执行其 while 循环!因此,siTurn 可能会在任何线程进入阶段 2 之前保持递增。
我知道我应该以更好的方式使用信号量 s2 并尝试从中受益,而不是将其用作互斥体。任何新的解决方案或修复我当前的解决方案?或使用信号量的通用解决方案,以便我可以将其应用于我的代码。