Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用2个线程从gsm调制解调器拾取sms_Java_Multithreading_Sms_Gsm_Modem - Fatal编程技术网

Java 使用2个线程从gsm调制解调器拾取sms

Java 使用2个线程从gsm调制解调器拾取sms,java,multithreading,sms,gsm,modem,Java,Multithreading,Sms,Gsm,Modem,正在尝试执行一个应用程序,该应用程序在一段时间内从gsm调制解调器读取sms 思考这个解决方案: 我的应用程序中有2个线程 T1-GSMModemHandler,是串行通信的处理程序。 T2-SMSPicker,它在每个时间段请求sms并对其执行一些字符串算法 我希望我的应用程序能够这样做: T2使用readAllMessages(GSMModemHandler类中的一种方法)请求sms,然后保持阻止状态 B-T1有一个SerialEventListener,因此它侦听对GSM调制解调器发送的请

正在尝试执行一个应用程序,该应用程序在一段时间内从gsm调制解调器读取sms

思考这个解决方案:

我的应用程序中有2个线程

T1-GSMModemHandler,是串行通信的处理程序。 T2-SMSPicker,它在每个时间段请求sms并对其执行一些字符串算法

我希望我的应用程序能够这样做:

T2使用readAllMessages(GSMModemHandler类中的一种方法)请求sms,然后保持阻止状态

B-T1有一个SerialEventListener,因此它侦听对GSM调制解调器发送的请求的响应,并将其发送回T2

C-一旦响应在T2类的列表中可用,T2将恢复其关于字符串算法的任务,然后在等待一定时间后从a再次执行相同的操作

我试着编写代码,当我启动应用程序时,它会工作一段时间,然后阻塞,我猜问题来自两个线程之间的错误理解,但找不到问题所在以及如何解决

这是我的代码和结果:

public class GSMModemHandler extends SerialPort implements 
SerialPortEventListener{

private static final String
        COMMAND_REMISE_A_ZERO = "ATZ",
        COMMAND_SMS_MODE_TEXT = "AT+CMGF=1",
        COMMAND_DETAILED_ERRORS = "AT+CMEE=1",
        COMMAND_SET_UP_MEMORIES = "AT+CPMS=\"MT\",\"MT\",\"MT\"",

        COMMAND_LIST_SUPPORTED_STORAGE_MODES = "AT+CPMS=?",

        COMMAND_ENVOIE_SMS = "AT+CMGS=",

        COMMAND_GET_ALL_SMS = "AT+CMGL=\"ALL\"",
        COMMAND_GET_NEW_SMS = "AT+CMGL=\"REC UNREAD\"",

        COMMAND_DELETE_ALL_MESSAGES = "AT+CMGD=0[,4]",
        COMMAND_DELETE_READ_MESSAGES = "AT+CMGD=0[,1]";

private SMSPicker smsPicker = null;
private String response = "";

public GSMModemHandler(String port) throws SerialPortException{
    super(port);        
    this.openPort();
    this.setParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
    this.addEventListener(this);
    this.startGsm();    
}

public void startGsm() throws SerialPortException{
    this.writeString(GSMModemHandler.COMMAND_REMISE_A_ZERO + "\r\n");
    this.writeString(GSMModemHandler.COMMAND_SMS_MODE_TEXT + "\r\n");
    this.writeString(GSMModemHandler.COMMAND_DETAILED_ERRORS + "\r\n");
    this.writeString(GSMModemHandler.COMMAND_SET_UP_MEMORIES + "\r\n");
}

public void sendMessage(SMS sms){
    try{
        if(this.isOpened()){ 
            this.writeString(GSMModemHandler.COMMAND_ENVOIE_SMS + "\"" + sms.getCorrespondantSms() + "\"\r\n");
            this.writeString(sms.getContenuSms() + '\032');
        }
    }
    catch(SerialPortException exp){
        exp.printStackTrace();
    }
}

public void readAllMessages(){
    try{
        if(this.isOpened())
            this.writeString(GSMModemHandler.COMMAND_GET_ALL_SMS + "\r\n");

    }
    catch(SerialPortException exp){
        exp.printStackTrace();
    }
}

public void readUnreadMessages(){
    try{
        if(this.isOpened())
            this.writeString(GSMModemHandler.COMMAND_GET_NEW_SMS + "\r\n");
    }
    catch(SerialPortException exp){
        exp.printStackTrace();
    }
}

public void deleteAllMessages(){
    try{
        if(this.isOpened())
            this.writeString(GSMModemHandler.COMMAND_DELETE_ALL_MESSAGES + "\r\n");
    }
    catch(SerialPortException exp){
        exp.printStackTrace();
    }
}

public void deleteReadMessages(){
    try{
        if(this.isOpened())
            this.writeString(GSMModemHandler.COMMAND_DELETE_READ_MESSAGES + "\r\n");
    }
    catch(SerialPortException exp){
        exp.printStackTrace();
    }
}

public synchronized void fermerConnexion(){
    try{
        this.closePort();
    }
    catch(SerialPortException exp){
        exp.printStackTrace();
    }
}

AtomicBoolean nextResponseIsSms = new AtomicBoolean(false);

@Override
public void serialEvent(SerialPortEvent spe) {
        try {
            String reponse = this.readString();

            System.out.println("GSM response = " + reponse);

            // If the next response contains the wanted sms
            if(reponse != null && reponse.contains("AT+CMGL=")){
                this.nextResponseIsSms.set(true);
                System.out.println("nextResponseIsSms = true");
            }

            // if the response contains sms
            else if(this.nextResponseIsSms.get()){

                this.smsPicker.getResponse().add(reponse);

                System.out.println("response sent !");

                this.deleteAllMessages(); // deleting the sms in the gsm modem

                System.out.println("messages deleted");

                this.nextResponseIsSms.set(false);

                System.out.println("nextResponseIsSms = false");

                // gives the SMSPicker the hand to treat the response
                synchronized(this.smsPicker){ this.smsPicker.notify(); } 

                System.out.println("smsPicker notified");
            }

    } catch (SerialPortException ex) {
        Logger.getLogger(GSMModemHandler.class.getName()).log(Level.SEVERE, null, ex);
    } 
}
/**
 * @return the smsPicker
 */
public SMSPicker getSmsPicker() {
    return smsPicker;
}

/**
 * @param smsPicker the smsPicker to set
 */
public void setSmsPicker(SMSPicker smsPicker) {
    this.smsPicker = smsPicker;
}
}

结果:

注意:在红线处发生的阻塞状态BUILD STOPPED仅仅是我通过kill停止应用程序的结果


提前谢谢

最有可能的情况是,您遇到了一个丢失的信号:您开始等待已经发生的通知

这是因为你开始无条件地等待。但是,您应该始终在检查其等待条件的循环中等待

在你的情况下,继续等待可能是直到一个答案已经提供

因此:

您还必须确保在您的情况下,在SMSPicker上同步的监视器正确地保护确定条件的状态。因为您似乎只是公开了响应队列,所以它认为情况可能并非如此,但我遗漏了太多细节,无法确定


要获得更详细的解释,请查看。

谢谢,y,像一个符咒一样工作,编码为whilethis.responses.isEmpty this.wait;
public class SMSPicker extends ControlledThread{

private GSMModemHandler modemGsm;
private SMSQueueToDatabase smsQueueHandler;
private volatile Queue<String> responses = new LinkedList<String>();

public SMSPicker(double frequency, GSMModemHandler gsmModem){
    super(frequency);
    this.modemGsm = gsmModem;
    this.modemGsm.setSmsPicker(this);
    this.smsQueueHandler = new SMSQueueToDatabase(frequency);
}

@Override
public void whatToDoBeforeTheLoop(){
    this.smsQueueHandler.start();

    try {
        this.wait(2 * this.waitingPeriod.get());
    } catch (InterruptedException ex) {
        Logger.getLogger(SMSPicker.class.getName()).log(Level.SEVERE, null, ex);
    }
}

@Override
public void whatToDoDuringTheLoop() throws NullPointerException{
    synchronized(this){ 
        try {
            System.out.println("I'm going to launch the request !");

            // Sending the sms read request to the gsm modem
            this.modemGsm.readAllMessages();

            System.out.println("i'm going to be stopped!");

            // wait till we get the answer
            this.wait();

            System.out.println("I've been stopped and now resuming");
        } 
        catch (InterruptedException ex) {
            Logger.getLogger(SMSPicker.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    // Treating the response in order to extract sms from it
    while(!this.responses.isEmpty()){
        String longMessage = this.responses.poll();

        if(longMessage != null){
            String[] shortMessages = null;
            shortMessages = longMessage.split("\\+CMGL: [0-9]*,\"");

            if(shortMessages == null) continue;

            for(String shortMessage: shortMessages){
                int indexLastOK = shortMessage.lastIndexOf("OK");

                if(indexLastOK != -1 && shortMessage.contains("+")) 
                    this.smsQueueHandler.getSmsFifo().add(this.fromStringToSms(shortMessage
                            .substring(0,shortMessage.lastIndexOf("OK") - 2))); // if it is the last sms
                else if(shortMessage.contains("REC")) // if it is not the last one
                    this.smsQueueHandler.getSmsFifo().add(this.fromStringToSms(shortMessage));
            }
        }
    }    
}

private SMS fromStringToSms(String stringSms){  
    String[] smsParts = stringSms.split(",");

    String correspondantSms = smsParts[1].replaceAll("\"", "");        
    String dateSms = smsParts[3].replace("\"","").replaceAll("/", "-");
    String heureSms = smsParts[4].substring(0,smsParts[4].lastIndexOf("\"")).substring(0, 8);
    String contenuSms = stringSms.substring(stringSms.lastIndexOf("\"") + 3);

    LocalDateTime momentSms = LocalDateTime.parse("20" + dateSms + "T" + heureSms);

    return new SMS(correspondantSms,contenuSms,momentSms);
}

@Override
public void whatToDoAfterTheLoop() {
}

/**
 * @return the modemGsm
 */
public GSMModemHandler getModemGsm() {
    return modemGsm;
}

/**
 * @param modemGsm the modemGsm to set
 */
public void setModemGsm(GSMModemHandler modemGsm) {
    this.modemGsm = modemGsm;
}

/**
 * @return the smsQueueHandler
 */
public SMSQueueToDatabase getSmsQueueHandler() {
    return smsQueueHandler;
}

/**
 * @param smsQueueHandler the smsQueueHandler to set
 */
public void setSmsQueueHandler(SMSQueueToDatabase smsQueueHandler) {
    this.smsQueueHandler = smsQueueHandler;
}

/**
 * @return the response
 */
public Queue<String> getResponse() {
    return responses;
}

/**
 * @param response the response to set
 */
public void setResponse(Queue<String> responses) {
    this.responses = responses;
}
public abstract class ControlledThread extends Thread{

protected AtomicBoolean workable = null;
protected AtomicLong waitingPeriod = null;

public ControlledThread(double frequency){
    super();
    this.workable = new AtomicBoolean(true);
    this.waitingPeriod = new AtomicLong(((long)(1000 / frequency)));
}

@Override
public synchronized void run() {
    this.whatToDoBeforeTheLoop();
    while(this.workable.get()){
        try{
            this.whatToDoDuringTheLoop();
            this.wait(this.waitingPeriod.get());
        }
        catch(InterruptedException exp){
            exp.printStackTrace();
        }
    }
    this.whatToDoAfterTheLoop();
}

public void stopWorking(){
    this.workable.set(false);
}

public synchronized boolean isWorking(){
    return this.workable.get();
}

public abstract void whatToDoBeforeTheLoop();
public abstract void whatToDoDuringTheLoop();
public abstract void whatToDoAfterTheLoop();
}
while (!hasAnswer()) {
    this.wait();
}