我已经创建了一个游戏,并且希望在闲坐一段时间后将其删除。一个可运行的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());
         }
       }
     }
   }
  }
 }

最佳答案

对于大多数任务,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);
   }
 }

08-04 10:47