【问题标题】:Java - is this missed signal solution ok?Java - 这个错过的信号解决方案可以吗?
【发布时间】:2015-09-09 18:12:48
【问题描述】:

我创建了一个游戏,我希望玩家在闲置一段时间后被移除。可运行的 PlayerRemover 类包含可运行的 GameTimer 类的实例。 PlayerRemover 创建一个 GameTimer 线程,该线程超时或手动停止,之后它通知 PlayerRemover 线程继续。

我担心如果在 wait() 之前调用 notify() 可能会丢失信号,因此我决定让 GameTimer 线程通知,直到 PlayerRemover 线程将 GameTimer 中的布尔变量设置为 false。

我在网上寻找了几个解决信号丢失的解决方案,但没有提到这一点,而使用带有原子代码块的 while 循环让我想知道这样做是否有充分的理由。

我的代码运行良好,但是这种方法会出现问题吗?有没有更好更标准的方法来做到这一点?

感谢您的帮助,谢谢!

public class PlayerRemover implements Runnable
{
  private final GameTimer timer;
  private final int seat;
  private final BlackjackPlayer p;
  private boolean wasSignalled;

  public PlayerRemover(TableFrame gui, GameTimer t)
  {
    timer = t;
    seat = gui.getTablePanel().getSeatIndex() ;
    p = gui.getTablePanel().getBlackjackPlayer();
    wasSignalled = false;
  }        

  @Override
  public void run()
  {
     Thread timerThread = new Thread(timer);
     timerThread.start();

     synchronized(timerThread)
     {    
       while (g[seat] != null && p.getState() == State.SITTING_OUT &&          timer.getSecondsLeft() > 0)
       {
           try {
               timerThread.wait();
           } catch (InterruptedException ex) {
               Logger.getLogger(TableCoord.class.getName()).log(Level.SEVERE, null, ex);
           }
       }
     }  

     timer.setSignalRecieved();
     timer.stopTimer();

     if (g[seat] != null && timer.getSecondsLeft() == 0)
     {
       removePlayer(p,seat);
       updateAllGUIs();
     }    
  }        
}



public class GameTimer implements Runnable {

private int secondsLeft; 
private boolean timerStop; 
private boolean doNotify;
private boolean signalReceived;

/**
* Creates a timer with a given number of seconds on the clock.
*/
public GameTimer(int seconds,boolean notifyThis)
{      
  secondsLeft = seconds;
  timerStop = false; 
  doNotify = notifyThis;
  signalReceived = false;
}

public GameTimer(int seconds)
{     
  secondsLeft = seconds;
  timerStop = false; 
  doNotify = false;
}

/**
* Stops timer permanently 
*/
public void stopTimer()
{
  timerStop = true;
}

public int getSecondsLeft()
{
   return secondsLeft;   
}         

public boolean getTimerStop()
{
  return timerStop;
 }         

public void setSignalRecieved()
{
 signalReceived = true;
}



 @Override
 public void run()
 {
   // While there timer is still counting down or all players finish 
   // their actions.
    while (!timerStop)
    {    
      // Wait 1 second  
      try
      {
       Thread.sleep(1000);
      }
      catch (Exception e)
      {
        System.out.println("Error: " + e.toString());
      }  

      //decrement timer 1 second
       secondsLeft--;

      if (secondsLeft <= 0)
      {
       timerStop = true;
      } 
    } 

    timerStop= true;
    if (doNotify)
    {  
     while (!signalReceived) 
    {    
       synchronized(this)
       {
         notify();
         try
         {
           Thread.sleep(100);
         }
         catch (Exception e)
         {
           System.out.println("Error: " + e.getMessage());
         }    
       }
     } 
   }
  }
 }

【问题讨论】:

    标签: java concurrency signals wait notify


    【解决方案1】:

    对于大多数任务,wait() 和 notify() 方法通常太低级并且容易出错。 ScheduledExecutorService

    是安排任务的一种简单且高级的方法

    其 JavaDoc 中的一个示例演示了固定速率可重复任务和一次性任务:

    这是一个类,它的方法设置 ScheduledExecutorService 在一个小时内每十秒发出一次哔声:

    import static java.util.concurrent.TimeUnit.*;
    
    
    class BeeperControl {
       private final ScheduledExecutorService scheduler =
         Executors.newScheduledThreadPool(1);
    
       public void beepForAnHour() {
         final Runnable beeper = new Runnable() {
           public void run() { System.out.println("beep"); }
         };
         final ScheduledFuture<?> beeperHandle =
           scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
         scheduler.schedule(new Runnable() {
           public void run() { beeperHandle.cancel(true); }
         }, 60 * 60, SECONDS);
       }
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-17
      • 1970-01-01
      • 1970-01-01
      • 2011-08-18
      • 1970-01-01
      • 2010-11-08
      相关资源
      最近更新 更多