- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
尝试执行一个应用程序,每隔一段时间从 gsm 调制解调器读取短信。
思考这个解决方案:
我的应用程序中有 2 个线程。
T1)- GSMModemHandler,它是串行通信的处理程序。T2)- SMSPicker,每个时间段都会请求短信并对其执行一些字符串算法。
我希望我的应用程序这样做:
A)- T2 使用 GSMModemHandler 类的方法 readAllMessages() 请求短信,然后保持阻塞状态。
B)- T1 有一个 SerialEventListener,因此它监听对 GSM-Modem 发送的请求的响应,并将其发送回 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;
}
}
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();
}
注意:阻塞状态发生在红线处(BUILD STOPPED 只是我通过杀死停止应用程序的结果)
提前致谢!
最佳答案
很可能,您遇到了错过的信号:您开始等待已经发生的 notify()
。
这是因为你开始无条件等待。但是,您应该始终在检查其等待条件的循环内等待。
就您的情况而言,继续等待的理由可能是直到提供答案为止。
所以:
while (!hasAnswer()) {
this.wait();
}
您还必须确保同步的监视器(在您的情况下为 SMSPicker
)正确保护确定条件的状态。由于您似乎只是暴露了响应队列,因此它认为情况可能并非如此,但我错过了太多细节,无法确定。
有关更详细的说明,请查看 here .
关于java - 使用 2 个线程从 gsm 调制解调器获取短信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47555566/
我需要您在以下方面提供帮助。近一个月来,我一直在阅读有关任务和异步的内容。 我想尝试在一个简单的 wep api 项目中实现我新获得的知识。我有以下方法,并且它们都按预期工作: public Htt
我的可执行 jar 中有一个模板文件 (.xls)。不需要在运行时我需要为这个文件创建 100 多个副本(稍后将唯一地附加)。用于获取 jar 文件中的资源 (template.xls)。我正在使用
我在查看网站的模型代码时对原型(prototype)有疑问。我知道这对 Javascript 中的继承很有用。 在这个例子中... define([], function () { "use
影响我性能的前三项操作是: 获取滚动条 获取偏移高度 Ext.getStyle 为了解释我的应用程序中发生了什么:我有一个网格,其中有一列在每个单元格中呈现网格。当我几乎对网格的内容做任何事情时,它运
我正在使用以下函数来获取 URL 参数。 function gup(name, url) { name = name.replace(/[\[]/, '\\\[').replace(/[\]]/,
我最近一直在使用 sysctl 来做很多事情,现在我使用 HW_MACHINE_ARCH 变量。我正在使用以下代码。请注意,当我尝试获取其他变量 HW_MACHINE 时,此代码可以完美运行。我还认为
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 关闭 9 年前。 要求提供代码的问题必须表现出对所解决问题的最低限度的理解。包括尝试过的解决方案、为什么
由于使用 main-bower-files 作为使用 Gulp 的编译任务的一部分,我无法使用 node_modules 中的 webpack 来require 模块code> dir 因为我会弄乱当
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 5 年前。 Improve this qu
我使用 Gridlayout 在一行中放置 4 个元素。首先,我有一个 JPanel,一切正常。对于行数变大并且我必须能够向下滚动的情况,我对其进行了一些更改。现在我的 JPanel 上添加了一个 J
由于以下原因,我想将 VolumeId 的值保存在变量中: #!/usr/bin/env python import boto3 import json import argparse import
我正在将 MSAL 版本 1.x 更新为 MSAL-browser 的 Angular 。所以我正在尝试从版本 1.x 迁移到 2.X.I 能够成功替换代码并且工作正常。但是我遇到了 acquireT
我知道有很多关于此的问题,例如 Getting daily averages with pandas和 How get monthly mean in pandas using groupby但我遇到
This is the query string that I am receiving in URL. Output url: /demo/analysis/test?startDate=Sat+
我正在尝试使用 javascript 中的以下代码访问 Geoserver 层 var gkvrtWmsSource =new ol.source.ImageWMS({ u
API 需要一个包含授权代码的 header 。这就是我到目前为止所拥有的: var fullUrl = 'https://api.ecobee.com/1/thermostat?json=\{"s
如何获取文件中的最后一个字符,如果是某个字符,则删除它而不将整个文件加载到内存中? 这就是我目前所拥有的。 using (var fileStream = new FileStream("file.t
我是这个社区的新手,想出了我的第一个问题。 我正在使用 JSP,我成功地创建了 JSP-Sites,它正在使用jsp:setParameter 和 jsp:getParameter 具有单个字符串。
在回答 StoreStore reordering happens when compiling C++ for x86 @Peter Cordes 写过 For Acquire/Release se
我有一个函数,我们将其命名为 X1,它返回变量 Y。该函数在操作 .on("focusout", X1) 中使用。如何获取变量Y?执行.on后X1的结果? 最佳答案 您可以更改 Y 的范围以使其位于函
我是一名优秀的程序员,十分优秀!