【问题标题】:When pressed a button it stuck in while infinite loop当按下一个按钮时,它卡在了无限循环中
【发布时间】:2019-07-18 03:48:56
【问题描述】:

对于我正在尝试的项目,通过按下按钮并在按下停止按钮时重新释放它来让 RFID 扫描仪一直运行,但是我试图在一个 while 循环中但问题似乎是,当我按下按钮代码一切正常,它确实进入一个循环但是在按下按钮后它不允许我按下其他任何东西,因为它卡在while循环中,有没有办法让它保持循环但同时能够用停止按钮停止它。

  @Override
public void start() {

    while (this.flag) {
        try {
            TerminalFactory factory = TerminalFactory.getDefault();
            List<CardTerminal> terminals = factory.terminals().list();
            System.out.println("Terminals: " + terminals);

            CardTerminal terminal = terminals.get(0);

            System.out.println("Waiting for a card..");
            if (terminal == null) {
                return;
            }
            terminal.waitForCardPresent(0);

            Card card = terminal.connect("T=1");
            System.out.println("Card: " + card);
            System.out.println("Protocol: " + card.getProtocol());
            CardChannel channel = card.getBasicChannel();

            ResponseAPDU response = channel.transmit(new CommandAPDU(new byte[]{(byte) 0xFF, (byte) 0xCA, (byte) 0x00, (byte) 0x00, (byte) 0x00}));
            System.out.println("Response: " + response.toString());
            if (response.getSW1() == 0x63 && response.getSW2() == 0x00) {
                System.out.println("Failed");
            }
            System.out.println("UID: " + bin2hex(response.getData()));

            getUid = bin2hex(response.getData());

            Thread.sleep(1000);
        } catch (CardException e) {
            System.out.println();
            JOptionPane.showMessageDialog(null, "Device Not Connected  " + e.getMessage());
        } catch (InterruptedException ex) {
            Logger.getLogger(CardId.class.getName()).log(Level.SEVERE, null, ex);
        }
}
}

对于我的开始按钮

 t = new CardId();
    t.start();

这是我的停止按钮

 t.flag = false;

【问题讨论】:

  • 我猜CardId 扩展了Thread
  • 是的,它是 CardId 类扩展线程
  • 切题,扩展Thread 是一种有点“弃用”的并发方式,您至少应该使用Runnables 并传递给Thread 的构造函数。
  • 如果@Rogue 的回答不能帮助解决您的问题,那么您可能需要创建一个有效的minimal reproducible example,然后将此代码发布到您的问题中。为此,您需要将所有非核心库调用替换为模拟调用,例如 Thread.sleep 以替换长时间运行的代码部分。这需要你付出相当多的努力才能做好,但如果需求很大,那么付出的努力可能是值得的。很幸运。

标签: java netbeans while-loop rfid


【解决方案1】:

首先,如果你使用的是线程,你应该重写“run()”方法。不是“start()”方法。您只需要使用“start()”方法来执行线程。否则,它将使用主线程。没有多线程。

第二件事是,如果“this.flag”是线程中的一个实例变量,并且它的值是由按钮操作动态更改的,那么该变量应该是易失的。否则,它通常会缓存在循环中。 (more)

建议:请遵循良好的设计模式。 (观察者)

【讨论】:

  • 完全跳过覆盖#run,只使用Runnable
【解决方案2】:

不要让您的Thread 在按下按钮时循环,而不是在按下按钮时停止,而是让循环不断运行。当Thread 到达其所需代码主体it does not execute a second time 的末尾时,即使在调用Thread#start 之后也是如此。

简而言之,您只需检查循环中t.flag 的值,如果是false,那么您可以让线程休眠,直到循环的下一次迭代。

【讨论】:

  • if (flag = true) { try { this.sleep(1000); } catch (InterruptedException ex) { Logger.getLogger(CardId.class.getName()).log(Level.SEVERE, null, ex); } } else if (flag = false) { this.stop();会是这样吗? @流氓
  • 不完全是,你也会在flag 变量上为false 睡觉。在这个设计案例imo中退出程序应该是一个完全独立的控件
猜你喜欢
  • 1970-01-01
  • 2010-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-01
  • 2018-09-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多