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