2013-07-27 45 views
5

我想提出一个方案中的线程x个池与共享库存相互作用。在这种情况下,我使用ArrayList作为共享清单。在我的程序中,线程是生物所具有的工作的表征。生物属于派对并共享用于执行工作的工件池。我只有一个生物可以随时与泳池互动。线程不沟通

出于某种原因,我一直有与线程的通信问题。我已经设置好了,所以如果游泳池没有被使用,生物会将其所有物品放入水池并开始通过它。如果他们无法找到任何他们需要他们应该所有他们需要的神器落入池中,将池不旺,那么信号一个生物等待,这是为他们准备好要经过它的游泳池以及。

我的问题是,如果一个生物翻翻池,而另一个在等待,它不能找到它喜欢它重复这个过程不会通知或让其他生物通过它去。

我所尝试的:我最初尝试使用锁,但锁不会向其他线程发出信号。然后我重写了它利用同步(党)。然后,我认为这是因为线程被撞毁的地方,但一个线程可以通过运行所有的方式,甚至抛售其项背入池的作业完成时(给予动物未锁定池成地狱)。

boolean ready = target.hasReqArtifacts(reqStones, reqPotions, reqWands, reqWeapons); 
    //checks to see if creature already has correct amount of each item. 
    //If it does it should skip pool interaction until it dumps its used items 
    //back into the pool. 
    System.out.println("Ready: " + ready); 
    while (!ready) {//begin pool interaction 
     synchronized (target.poolParty){ 
      System.out.println("Ready: " + ready); 
      System.out.println(this); 
      while (target.poolParty.busyPool) {//busyPool is initialized false 
       startJob.setEnabled(false); 
       try { 
        target.poolParty.wait(); 
       } catch (InterruptedException e) {} 
      } 
      synchronized (target.poolParty) { 
       target.poolParty.busyPool = true; 
       target.poolParty.notifyAll();//notify all threads that they need to wait because this one will proceed 
      } 
     } 
     target.releaseArtifacts();// adds all artifacts held by creature to an arraylist in poolParty 
            //then clears the creatures inventory 
     target.pickUpArtifacts(reqStones, reqPotions, reqWands, reqWeapons); 

     ready = target.hasReqArtifacts(reqStones, reqPotions, reqWands, reqWeapons); 
     if (ready) { 
      synchronized (target.poolParty) { 
       System.out.println("has required Items"); 
       target.poolParty.busyPool = false; 
       target.poolParty.notify(); 
      } 
     } else { 
      synchronized (target.poolParty) { 
       System.out.println("Does not has required Items"); 
       target.poolParty.busyPool = false; 
       target.releaseArtifacts(); 
       target.poolParty.notifyAll(); 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e){} 
      } 
     } 
    }//end pool interaction 

我在一个生物有一个以上的工作,但只能做一次一个工作的情景线程之间进行这种互动和它完美的作品。我量身定制了适合这种情况的方法,但我仍然遇到问题。

注意:我对并发性非常陌生,所以请原谅我,如果我的词汇量不是主题发展的话。

回答

1

看起来你是在使用target.poolParty同步块睡觉。这意味着等待访问该池的其他线程将无法访问它,因为该线程正在阻止它。将该块外部的sleep()移动。

在另一个地方,您可以在已经用于同步的块中使用synchronized (target.poolParty)。这是不必要的(好吧,整个代码块是不必要的,我把它删除了,只是指出)。另外wait()notify*()是低级同步原语并且很少需要。

boolean ready = target.hasReqArtifacts(reqStones, reqPotions, reqWands, reqWeapons); 
//checks to see if creature already has correct amount of each item. 
//If it does it should skip pool interaction until it dumps its used items 
//back into the pool. 
System.out.println("Ready: " + ready); 
while (!ready) { 
    // begin pool interaction 
    synchronized (target.poolParty) { 
     target.pickUpArtifacts(reqStones, reqPotions, reqWands, reqWeapons); 
     ready = target.hasReqArtifacts(reqStones, reqPotions, reqWands, reqWeapons); 

     /* I'd move this here. If we never release out items then the 
      other party members can't use them while this one still does 
      not have the needed items. Now they will be available to 
      other parties while this thread sleeps. */ 
     if (!ready) { 
      // adds all artifacts held by creature to an arraylist in poolParty 
      target.releaseArtifacts(); 
     } 
    } 

    // These don't access the pool, so they can be outside the synchronized block 
    if (ready) { 
     System.out.println("has required Items"); 
    } else { 
     System.out.println("Does not have required Items"); 
     // Sleep before the next try to get the required items. Lets other 
     // threads attempt to fetch their needed items 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      // Added, because silently eating exceptions is a bad idea 
      e.printStackTrace(); 
     } 
    } 
}//end pool interaction 
+0

谢谢你用我的方式向我解释我的错误。我能够将从中学到的知识融入到我取消工作和释放资源的代码中。 –

1

看起来像你在想这个问题。你的用例很简单。

  • 只有一个生物应该能够在任何给定时间访问游泳池。
  • 在此期间其他生物必须等待。
  • 这里的共享资源是池。

现在简单

synchronize(pool){ 
//doStuff 
} 

应该工作。

请注意,需要wait()notify()/notifyAll()是因为您需要同步代码的不同部分,而这些部分不会很好地落入单个连续的逻辑块。

boolean ready = target.hasReqArtifacts(reqStones, reqPotions, reqWands, reqWeapons); 
//checks to see if creature already has correct amount of each item. 
//If it does it should skip pool interaction until it dumps its used items 
//back into the pool. 
System.out.println("Ready: " + ready); 
if (!ready) {//begin pool interaction 
    synchronized (target.poolParty){ 
     System.out.println("Ready: " + ready); 
     System.out.println(this); 
     startJob.setEnabled(false); 
    } 
    target.releaseArtifacts();// adds all artifacts held by creature to an arraylist in poolParty 
           //then clears the creatures inventory 
    target.pickUpArtifacts(reqStones, reqPotions, reqWands, reqWeapons); 
    } 
}//end pool interaction