【问题标题】:Timer issues in java when using Timeout Exceptions, code doesn't run correctly after a Timeout Exception使用超时异常时java中的计时器问题,超时异常后代码无法正确运行
【发布时间】:2016-03-11 16:19:26
【问题描述】:

我正在用 java 设计一个游戏,它类似于棋盘游戏。在实现中还有一种称为速度模式的模式,如果一个玩家在时间限制(5 秒)内没有转弯,则另一个玩家获胜。这种模式通常也可以通过“捕获”对方棋子来获胜。在满足这些条件中的任何一个后,将从主菜单再次运行游戏。当通过捕获满足获胜条件时,这在正常模式和速度模式下都可以正常工作。当它被时间耗尽时,它的行为非常奇怪,几乎随机提示输入和打印。

当时的代码如下:

        public Boolean speedMode(Player player, Player opponent) {
            ExecutorService service = Executors.newSingleThreadExecutor();
            try {
                Runnable r = new Runnable() {
                    Boolean outOfRange;
                    public void run() {
                        do {
                            outOfRange = takeTurn(player);
                        } while (outOfRange == true);

                    }
                };
                Future<?> f = service.submit(r);
                f.get(5, TimeUnit.SECONDS);
            } catch (final InterruptedException e) {
                System.out.println("The thread was interrupted during sleep, wait or join");
            } catch (final TimeoutException e) {
                player.setWon(false);
                System.out.println("\n" + player.getName() +", you took too long... ");
                return true;
            } catch (final ExecutionException e) {
                System.out.println("An exception from within the Runnable task");
            }

            return false;
        }

当 TimeoutException 发生时,相反的玩家获胜,而下面显示的循环退出并打印正确的祝贺。问题是当它在代码的最后一行开始新游戏时,就是奇怪行为开始的时候。定时器方法中是否有我需要关闭的东西?它几乎就像它仍在后台运行一样。

else {

                do {
                    timeOut = speedMode(second, first);

                    if(winCheck1(first) == true || timeOut == true){
                        break;
                    }

                    timeOut = speedMode(first, second);

                } while (winCheck1(second) != true && timeOut != true);

                if(player1.isWon() == true){
                    System.out.println("\n\nCongratulations " + player1.getName() + " you are the winner!\n\n");
                }

                else{
                    System.out.println("\n\nCongratulations " + player2.getName() + " you are the winner!\n\n");
                }

            }

            //reload the menu
            Game game = new Game();
        }

基本上我的问题是;谁能告诉我为什么在抛出 TimeoutException 后开始新游戏无法正常工作?

【问题讨论】:

    标签: java timer exception-handling timeoutexception


    【解决方案1】:

    在计时器方法中我是否需要关闭一些东西?它几乎就像它仍在后台运行一样。

    如果您不在执行程序上调用关闭,执行程序创建的工作线程将挂起。 (这与您声明执行程序的范围无关。)如果它是一个非守护线程,那么它将保持旧 JVM 处于活动状态。

    您的任务还需要对中断做出响应。请参阅 shutdownNow 的文档:

    除了尽力停止处理正在执行的任务之外,没有任何保证。例如,典型的实现将通过 Thread.interrupt() 取消,因此任何未能响应中断的任务都可能永远不会终止。

    “响应中断”是指检查Thread.currentThread().isInterrupted()看线程是否已经被取消然后对它进行操作(找到一个停止的地方,做清理,并退出运行方法),并恢复中断标志(@987654322 @) 如果捕获到 InterruptedException 或 InterruptedIOException。

    【讨论】:

    • 谢谢!但是,我对如何执行此操作感到有些困惑,因为这是我第一次处理 ExecutorService。我尝试调用 service.shutdownNow();在抛出异常以尝试将其关闭但它似乎不起作用之后,关于我做错了什么有什么建议吗?
    • @K.McDonald:不知道您的 takeTurn 方法在做什么,如果它不处理中断,则关闭将不起作用,请参阅我的编辑。
    猜你喜欢
    • 2021-01-29
    • 1970-01-01
    • 2021-03-12
    • 2012-02-23
    • 2019-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-12
    相关资源
    最近更新 更多