我想确保我的serialevents不会受到其他类的影响



我正在编写与几台机器串行通信的代码。每台机器与通信器类的一个实例交互,该类具有串行端口事件侦听器。

当机器接收到足够的数据时,它执行二次测试。(不能帮助,因为测试本身是二次的),输入可能很大。因此,如果代码正在进行计算,我担心一些串行事件不会被注册。

作为一种解决方案,我考虑创建一个线程来运行计算,并将其设置为休眠,休眠时间由连接的机器数量决定。然而,我当时认为,也许这将是一个更好的主意,如果我能把线程休眠从serialevent方法?这是可能的还是线程不会运行,直到正在运行的方法完成?

现在,在下面的代码中,我已经包含了线程。如果serialevent不能中断线程 ,我将在计算方法中休眠。
private class CalculationThread implements Runnable{
@Override
  public void run() 
    {
          calculateResult();
    }
}}
private void calculateResult() {
    ArrayList<Double> theoretical_vals;
    ArrayList<ArrayList<Double>> theoretical_curves = new ArrayList();
    double current_maxdiff, maxdiff;
    double ao = measurements.get(0).getMeasurement();
    theoretical_vals = RadioCalculations.theoreticalVals(measurements, hf, ao);
    theoretical_curves.add(theoretical_vals);
    int index = 1;
    for (MeasurePoint m : measurements) {
        theoretical_vals = RadioCalculations.calibratecontrolValues(measurements, index, hf);
        try {
            Thread.sleep(20*(parent.getNumberOfTests()-1));} 
        catch (InterruptedException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
        }
        theoretical_curves.add(theoretical_vals);
        index++;
    }
    index = 1;
    maxdiff = 0;
    for (ArrayList a : theoretical_curves) {
        try {
            Thread.sleep(20*(parent.getNumberOfTests()-1));
        } catch (InterruptedException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
        }
        current_maxdiff = compareValues(a, measurements);
        if (current_maxdiff > maxdiff) {
            if (current_maxdiff > pass_limit) {
                passed = false;
                failed_measurementpoint = index;
                break;
            }
            maxdiff = current_maxdiff;
            index++;
        }
    }
    passed = true;
    max_dev = maxdiff;
    logResults();
}


public void serialEvent(SerialPortEvent spe) {
    try {
        Thread.sleep(10);
    } catch (InterruptedException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    }
   pauseListen(false);     
   if (spe.getEventType()== SerialPortEvent.DATA_AVAILABLE){   
         try {
    while (inputStream.available() > 0) {
                   numBytes =  inputStream.read(readBuffer);}} 
        catch (IOException e) {e.printStackTrace();}
        input_line= new String(readBuffer,0,numBytes);
        input_line = input_line.replaceAll("[nr]","*");
        buffer.append(input_line);
        if (input_line.contains("*")){   
        input_line= buffer.toString();
        input_line = input_line.replaceAll("[*]","");
        buffer.setLength(0);
        pauseListen(true);
        update(input_line);}}
}
} 

进程中有一个计算时,您可以使用BlockingQueue(自Java 5起)将新的计算放在此队列中。

首先,您需要一个包装器类来接收串行端口的数据:

class CalculationWrapper {
    // fields
    // getters setters
    public void calculateResult() {
        // operations
    }
}

计算方法calculateResult可以在这个类中或在下一个类中使用:

class Calculator implements Runnable {
    private final BlockingQueue<CalculationWrapper> queue;
    Calculator(BlockingQueue<CalculationWrapper> q) {
        queue = q;
    }
    public void run() {
        try {
            while (true) {
                CalculationWrapper wrapper = queue.take();
                wrapper.calculateResult();
            }
        } catch (InterruptedException ex) {
            // log error
        }
    }
}

take方法等待,直到队列中有更多的新计算。串行端口事件侦听器的类(以及用于存放新计算的类)可以是:

class Receiver implements Runnable, SerialPortEventListener {
    private final BlockingQueue<CalculationWrapper> queue;
    Receiver(BlockingQueue q) {
        queue = q;
    }
    public void run() {
        try {
            while (true) {
                Thread.sleep(1000);
            }
        } catch (InterruptedException ex) {
            // log
        }
    }
    public void serialEvent(SerialPortEvent evt) {
        switch (evt.getEventType()) {
            case SerialPortEvent.DATA_AVAILABLE:
                try {
                    // read
                    CalculationWrapper wrapper = new CalculationWrapper();
                    // set data on wrapper
                    queue.put(wrapper);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                break;
        }
    }
}

setup类的主类:

class Setup {
    public static void main(String args[]) {
        // get port
        // register listener
        BlockingQueue q = new ArrayBlockingQueue(10);
        Receiver p = new Receiver(q);
        Calculator c1 = new Calculator(q);
        new Thread(p).start();
        new Thread(c1).start();
    }
}

这在某种程度上。看到更多:

  • 课程:并发(Java教程>基本类)
  • SerialPort示例«javax.comm«Java by API
  • Java通信API:一个工作示例- By Rick Proctor

相关内容

  • 没有找到相关文章

最新更新