java - 使用计时器打破循环

标签 java loops timer

我正在尝试为调用/响应 ping 设置超时。这是为了确定在自动连接序列中使用哪个 CommPort。当我发送 CALL_SIGNAL byte[] 时,我希望得到“FU”回复。这就是我确定哪个是我的设备的方法。 SSCCE 如下(抱歉,篇幅较长,但这是缩短版本)

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Timer;
import java.util.TimerTask;
import javax.comm.CommPortIdentifier;
import javax.comm.CommPort;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;

public class PingTest {
    public static final long PING_TIMEOUT = 1000; // in millis
    public static final byte[] CALL_SIGNAL = {70, 68, 73, 68};

    public boolean ping(CommPortIdentifier cpi)  {
        System.out.println("Pinging " + cpi.getName());
        CommPort port = null;
        InputStream input = null;
        OutputStream output = null;

        //Initialization test
        try {
            port = cpi.open("pingTest", 50);
            input = port.getInputStream();
            output = port.getOutputStream();
        } catch (PortInUseException ex) {
            if (cpi.getCurrentOwner().startsWith("pingTest")) {
                System.out.println("Port already owned by this application.");
                return true;
            }
            return false;
        } catch (Exception ex) {
            try {
            port.close();
            } catch (NullPointerException e) {
            }
            System.out.println("Failed initialization test.");
            System.err.println(ex);
            return false;
        }
        System.out.println("Passed initialization test."); 

        //Call and response test
        final Stop stop = new Stop();
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {

            @Override
            public void run() {
                System.out.println("Stop timer triggered.");
                stop.shouldStop = true;
            }
        }, PING_TIMEOUT);
        try {
            System.out.println("Writing...");
            output.write(CALL_SIGNAL);
            System.out.println("Reading...");
            boolean waitForF = true;
            while (!stop.shouldStop && !stop.didPass) {
                if (waitForF) {
                    if ((byte) 'F' == input.read()) {
                        waitForF = false;
                    }
                } else {
                    System.out.println('F');
                    if ((byte) 'U' == input.read()) {
                        System.out.println('U');
                        stop.didPass = true;
                    } else {
                        System.out.println();
                        waitForF = true;
                    }
                }
            }
        } catch (IOException ex) {
            System.out.println("Failed I/O test.");
            return false;
        } finally {
            port.close();
        }

        if (stop.didPass) {
            System.out.println("Successful ping.");
            return true;
        }
        System.out.println("Failed call and response test.");
        return false;
    }

    public static void main(String[] args) {
        PingTest pinger = new PingTest();
        Enumeration<CommPortIdentifier> ports = CommPortIdentifier.getPortIdentifiers();
        boolean trigger = true;
        String name = null;
        while (trigger && ports.hasMoreElements) {
            CommPortIdentifier cpi = ports.nextElement();
            name = cpi.getName();
            trigger = !ping(cpi);
        }
        if (trigger) {
            System.out.println("Found it. It is " + name);
        } else {
            System.out.println("Not Found");
        }
    }
}

class Stop {
    boolean shouldStop = false;
    boolean didPass = false;
}

我的输出是:

Pinging COM1
Passed initialization test.
Writing...
Reading...
Stop timer triggered.

然后应用程序卡住。尝试使用 Timer 停止 while 循环是否存在问题?

最佳答案

您的读取被阻塞。您需要使用Timeouts

关于java - 使用计时器打破循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10888008/

相关文章:

java - 如何从java字符串中删除 "&nbsp;"

java - 通过改造进行最小的发布请求

loops - 从 Common Lisp 中的嵌套循环返回

java - toString() 不适用于父类(super class)和子类

c - 在 Linux 上用 C 调用异步、定时函数?

java - Selenium Java 如何在测试步骤失败时保持浏览器窗口打开

r - 在 R 中的大矩阵中添加连续的四/n 个数字

java - Java内部有Thread.sleep时定时器不会停止

swift - 更新标签,在 Swift 3 中每秒显示当前时间

java - 使用eclipse进行xslt远程调试