0

我在与设备进行串行通信时使用 java 线程。它在调试模式下工作得非常完美,但是当我运行程序时,线程不执行指令。我使用 RXTX 库进行串行通信,我的程序的其余部分在 JavaFX(应用程序)中。

这是用于串行通信的类(SerialClass.java):

import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Enumeration;

public class SerialClass implements SerialPortEventListener {

    public SerialPort serialPort;

    /**
     * The port we're normally going to use.
     */
    private static final String PORT_NAMES[] = {
        "/dev/tty.usbserial-A9007UX1", // Mac OS
        "/dev/ttyACM0", // Linux
        "COM21", // Windows
    };

    public static BufferedReader input;

    public static OutputStream output;

    /**
     * Milliseconds to block while waiting for port open
     */
    public static final int TIME_OUT = 2000;

    /**
     * Default bits per second for COM port.
     */
    public static final int DATA_RATE = 9600;

    public void initialize() {
        CommPortIdentifier portId = null;
        Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
        //First, Find an instance of serial port as set in PORT_NAMES.
        while (portEnum.hasMoreElements()) {
            CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
            for (String portName : PORT_NAMES) {
                if (currPortId.getName().equals(portName)) {
                    portId = currPortId;
                    break;
                }
            }
        }
        if (portId == null) {
            System.out.println("Could not find COM port.");
            return;
        }
        try {
            // open serial port, and use class name for the appName.
            serialPort = (SerialPort) portId.open(this.getClass().getName(), TIME_OUT);
            // set port parameters
            serialPort.setSerialPortParams(DATA_RATE,
                    SerialPort.DATABITS_8,
                    SerialPort.STOPBITS_1,
                    SerialPort.PARITY_NONE);
            // open the streams
            input = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
            output = serialPort.getOutputStream();
            char ch = 1;
            output.write(ch);
            // add event listeners
            serialPort.addEventListener(this);
            serialPort.notifyOnDataAvailable(true);
        } catch (Exception e) {
            System.err.println(e.toString());
        }
    }

    public synchronized void close() {
        if (serialPort != null) {
            serialPort.removeEventListener();
            serialPort.close();
        }
    }

    public synchronized void serialEvent(SerialPortEvent oEvent) {
        if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
            try {
                String inputLine = input.readLine();
                System.out.println(inputLine);
            } catch (Exception e) {
                System.err.println(e.toString());
            }
        }
    }

    public static synchronized void writeData(String data) {
        System.out.println("Sent: " + data);
        try {
            output.write(data.getBytes());
        } catch (Exception e) {
            System.out.println("could not write to port");
        }
    }
}

我正在使用另一个类 ImageInterface,它使用这个类:

import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.sanselan.ImageReadException;
import finImage.FinImage;
import img.ImageAccessor;
import img.ImageBean;

public class ImageInterface {

    String image;
    public static BufferedReader input;
    public static OutputStream output;

    public static synchronized void writeData(String data) {
        System.out.println("Sent: " + data);
        try {
            output.write(data.getBytes());
        } catch (Exception e) {
            System.out.println("could not write to port");
        }
    }

    public void openWithImage(File ImgFile) {

        try {
            // TODO code application logic here
            ImageAccessor sa = new ImageAccessor();
            ImageBean s = new ImageBean();
            String ImgId = FinImage.getImageFromFin(ImgFile);
            System.out.print(ImgId);
            String sm = ImgId.toString();
            System.out.print(sm);
            String imageid = FinImage.getImageFromFin(ImgFile);
            String sme;

            Boolean flag = false;

            if (imageid.startsWith("'")) {
                sme = imageid.substring(1, imageid.length() - 1);
            } else {
                sme = imageid;
            }
            s = sa.getAllImageInfoById(sme);
            System.out.print(s);
            image = s.getFinPin();
            //System.out.print(FinPin);
            //System.out.print(FinPin);S
            // image = ImgPin.toString();
            System.out.print(image);
            try {
                SerialClass obj = new SerialClass();
                int c = 0;
                obj.initialize();
                input = SerialClass.input;
                output = SerialClass.output;
                InputStreamReader Ir = new InputStreamReader(System.in);
                BufferedReader Br = new BufferedReader(Ir);

                Thread t = new Thread() {
                    public void run() {
                        obj.writeData(image);
                    }
                    //catch (InterruptedException ie){}
                };

                t.start();
                System.out.println("Started");

                obj.close();
            } catch (Exception e) {
            }
        } catch (ImageReadException ex) {
            Logger.getLogger(ImageInterface.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(ImageInterface.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

在上面的代码中,我正在访问 Image 中的 id,然后通过串行通信将其写入。在上面的程序中,线程在程序运行时不写入,但在程序调试时写入串行端口。我无法找出发生此类问题的确切原因。

我正在使用 Arduino 进行输出。此外,我一直在同时使用 2 个操作系统,Ubuntu 12.04LTS 和 Windows 7。在 Windows 7 中,线程在调试中执行,而在 Ubuntu 12.04 中,线程在启动时不会启动 run 方法。

请指出我在哪里犯了错误。

4

1 回答 1

0

您已经在“主”线程和“写入”线程之间创建了竞争条件。close您在启动写入线程后立即调用“主”线程。由于您不等待写入线程完成,因此您可能会在写入任何内容之前关闭通道。在“调试”模式下,事情往往会运行得更慢,因此在主线程调用 close 之前,写线程可能有时间完成。

一个简单的解决方案是在调用t.join()之前添加。obj.close()这将强制主线程等待写入线程完成。但是,在您当前的代码中,尚不清楚为什么要使用第二个线程进行编写。

于 2013-08-17T12:00:47.517 回答