当前位置: 首页 > 知识库问答 >
问题:

while循环不循环/显示计数

梅跃
2023-03-14

此方法重复读取命令并执行它们,直到游戏结束。完成的变量为true时,表示玩家/用户点击了退出并想要结束游戏——从而退出循环并执行到方法结束。

import org.apache.commons.lang3.time.StopWatch;

private Parser parser;
private Command command;
private StopWatch stopWatch;

public void play() 
{   

    stopWatch = new StopWatch();
    stopWatch.start();
    long timeLimit = 5000;

    boolean finished = false;

    printWelcome();

    while (finished == false) 
    {   
       System.out.println(stopWatch.getTime() + " milliseconds");
       if (stopWatch.getTime() >= timeLimit)
       {
          System.out.println("Time limit of " + timeLimit + " milli seconds has been reached. Good bye!");
          return;
       }
       else
       {
          command = parser.getCommand();
          finished = processCommand(command);
       }
    }     
    System.out.println("Thank you for playing.  Good bye.");       
}

但我观察到循环有一种奇怪的行为。它循环得非常好(省略以下行时显示stopWatch.getTime()的连续计数:

  else
  {
     command = parser.getCommand();
     finished = processCommand(command); 
  }

但是当我把它们放回去时,它会停止显示秒表的连续递增时间,因为它会朝着时间限制增加(在这一点上,它应该停止)。即使玩家没有输入任何命令或输入。

stopWatch显然在后台运行,但它不显示计数。

请指教。谢了。

共有3个答案

徐奇逸
2023-03-14

也许我误解了你的问题,但听起来你的问题不是连续打印?如果是这样,这是因为您的 parer 正在等待用户输入。线程可以解决此问题,运行计时器并在单独的线程中打印

狄卓君
2023-03-14

我假设您的< code > parser . get command();将一直阻塞,直到有输入为止。由于while循环在一个线程中运行,程序在这一点上停止。

检查我是否正确的最简单方法是输入任何命令,您应该从这行得到一些输出:

       System.out.println(stopWatch.getTime() + " milliseconds");

您要么需要在此方法中实现超时,要么需要第二个线程计算时间并中断等待。

解飞语
2023-03-14

即使玩家没有输入任何命令或输入。

如果解析器#getCommand 是一种等待用户输入的方法,则在用户输入之前,执行将被阻止。这意味着 while 循环不会运行,您也不会看到它打印出新的时间。

无论如何,按照你的要求去做会给用户带来非常不和谐的体验,因为这意味着当他们输入命令时,它会继续打印,这对用户来说不是很友好。

您可以使用生产者-消费者方法来实现这一点。我已经根据链接的问题改编了代码:

// Shared queue
final Queue<String> commands = new ConcurrentLinkedQueue<>();

// Non-blocking consumer
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(new Runnable() {
    @Override
    public void run() {
        // non-blocking
        if((String command = commands.poll()) != null) {
            processCommand(command);
        }
    }
}, 0, 10, TimeUnit.MILLISECONDS);

// Blocking producer (this is basically the logic from Parser#getCommand)
Scanner sc = new Scanner(System.in);
while(sc.hasNext()) {
    commands.add(sc.next());
}

然而,这个解决方案并没有真正让您实现超时。因此,您必须创建一个新的类来“包装”< code>Runnable,以便您可以在超时后取消它(类似于这种方法):

public class TimeOutableRunnable implements Runnable {

    private final Queue<String> commands;
    private final Runnable wrapped;
    private volatile ScheduledFuture<?> self;

    public TimeOutableRunnable(Runnable wrapped, Queue<String> commands) {         
        this.commands = commands;
        this.wrapped = wrapped;         
    }

    @Override
    public void run() {
        if(commands.isEmpty()) {
            self.cancel(false);
        } else {
            wrapped.run();
        }
    }

    public void runWithTimeout(ScheduledExecutorService executor, long timeout, TimeUnit unit) {
        self = executor.scheduleAtFixedRate(this, 0, timeout, unit);
    }
}

然后你可以做:

final Queue<String> commands = new ConcurrentLinkedQueue<>();
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
new TimeOutableRunnable(new Runnable() {
    @Override
    public void run() {
        // non-blocking
        while((String command = commands.poll()) != null) {
            processCommand(command);
        }
    }
}, commands).runWithTimeout(executor, timeLimit, TimeUnit.MILLISECONDS);

我还没有对此进行测试,我不会对并发性评价很高,所以如果这种方法存在根本性的问题,请告诉我。

 类似资料:
  • 只要给定条件为真,Perl编程语言中的while循环语句就会重复执行目标语句。 语法 (Syntax) Perl编程语言中while循环的语法是 - while(condition) { statement(s); } 这里的statement(s)可以是单个陈述或一个陈述块。 condition可以是任何表达。 当条件为真时,循环迭代。 当条件变为假时,程序控制将立即传递到循环之后的行。

  • 编写程序时,您可能会遇到需要反复执行操作的情况。 在这种情况下,您需要编写循环语句以减少行数。 JavaScript支持所有必要的循环,以减轻编程压力。 while循环 JavaScript中最基本的循环是while循环,将在本章中讨论。 while循环的目的是只要expression为真,就重复执行语句或代码块。 表达式变为false,循环终止。 流程图 while loop流程图如下 - 语法

  • 只要给定条件为真,Objective-C编程语言中的while循环语句就会重复执行目标语句。 语法 (Syntax) Objective-C编程语言中while循环的语法是 - while(condition) { statement(s); } 这里, statement(s)可以是单个语句或语句块。 condition可以是任何表达式,true是任何非零值。 当条件为真时,循环迭代。

  • While循环一次又一次地执行相同的代码,直到满足停止条件。 语法 (Syntax) 在R中创建while循环的基本语法是 - while (test_expression) { statement } 流程图 (Flow Diagram) 这里while循环的关键点是循环可能永远不会运行。 当测试条件并且结果为假时,将跳过循环体并且将执行while循环之后的第一个语句。 例子 (Exam

  • 在给定条件为真时重复语句或语句组。 它在执行循环体之前测试条件。 只要给定条件为真, while循环语句就会重复执行目标语句。 语法 (Syntax) 以下是while循环的语法。 while(condition){ statement(s); } 这里, statement(s)可以是单个语句或语句块。 condition可以是任何表达式,true是任何非零值。 当条件为真时,循环迭代。

  • 只要给定条件为真,Swift 4编程语言中的while循环语句就会重复执行目标语句。 语法 (Syntax) Swift 4编程语言中while循环的语法是 - while condition { statement(s) } 这里的statement(s)可以是单个陈述或一个陈述块。 condition可以是任何表达。 当条件为真时,循环迭代。 当条件变为假时,程序控制传递到紧接循环之后