我正在编写与几台机器串行通信的代码。每台机器与通信器类的一个实例交互,该类具有串行端口事件侦听器。
当机器接收到足够的数据时,它执行二次测试。(不能帮助,因为测试本身是二次的),输入可能很大。因此,如果代码正在进行计算,我担心一些串行事件不会被注册。
作为一种解决方案,我考虑创建一个线程来运行计算,并将其设置为休眠,休眠时间由连接的机器数量决定。然而,我当时认为,也许这将是一个更好的主意,如果我能把线程休眠从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