簡體   English   中英

使用計時器中斷循環

[英]Using a Timer to break a loop

我正在嘗試為呼叫/響應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循環是否存在問題?

您的閱讀受阻。 您需要使用超時

您正在從不同線程並發地訪問共享狀態( shouldStopdidPass變量),而沒有任何同步。 如果要確保閱讀其他線程寫的內容,則應同步每個訪問。

因此,或者添加方法來獲取和設置這些變量,並使這些方法同步,或者,如果每個變量代表彼此不同的信息並且可以獨立地進行寫入和讀取,則使這些變量易變。

第三種方法(僅在與易失性解決方案相同的條件下有效)是使用AtomicBoolean變量而不是布爾變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM