我有一个线程必须在无限循环中进行arduino串行反馈。我觉得在Apache Tomcat服务器上做无限循环并不好。这种设计有哪些好的做法?
下载我从Servlet Context获得的单例,其中包含SerialAnswerMonitor类(它具有无限循环)
public enum DeviceMonitor { // this is a SINGLETON!
INSTANCE;
private Map<Integer, Device> devices; // made it a little more general - since x10 device also has the same implementation
private boolean isOutdated;
private boolean serialAnswer; // need the confirmation that the device really switched
private String feedback; // in case the device switches manually
private SerialAnswerMonitor serialMonitor;
DeviceMonitor() {
System.out.println(Notifications.NOTIF_CREATED_DEVICEMONITOR_SINGLETON);
this.devices = new HashMap<Integer, Device>();
// maps the house in the format order <-> device
/*arduinoDevices.put(0, new RfCoded("air conditioner", false, "test1", "test"));
arduinoDevices.put(1, new RfCoded("bathroom lights", false, "test2", "test"));
arduinoDevices.put(2, new RfCoded("corridor lights", false, "test3", "test"));
arduinoDevices.put(3, new RfCoded("garden lights", false, "test4", "test"));*/
devices.put(4, new RfCoded("kitchen", false, "a", "b"));
devices.put(5, new RfCoded("bedside", false, "c", "d"));
devices.put(6, new RfCoded("doorside", false, "e", "f"));
devices.put(7, new RfCoded("bathroom", false, "g", "h"));
devices.put(8, new RfCoded("room", false, "o", "p"));
devices.put(9, new AirConditioner("air conditioner", false, 18, 1, 4, "j", 28));
this.isOutdated = false;
this.serialAnswer = false;
this.setSerialMonitor(new SerialAnswerMonitor()); // wait for changes in serial feedback
}
public Device getDevice(String mapLocation) {
for(Device each : devices.values())
{
if (each.getLocation().equals(mapLocation)) {
return each;
}
}
return null;
}
public boolean isOutdated() {
return isOutdated;
}
public void setOutdated(boolean isOutdated) {
this.isOutdated = isOutdated;
}
public TreeMap<Integer, Device> getStatesTreeMap() {
return new TreeMap<Integer, Device>(devices);
}
/**
* Creates a json map for the reverse ajax, so that javascript populates
* the device list
* @return String of the json map
*/
public String createJsonMap() {
JSONObject json = new JSONObject();
JSONArray deviceList = new JSONArray();
JSONObject device;
//creates a ordered map of devices
TreeMap<Integer, Device> treeMap = new TreeMap<Integer, Device>(devices);
Integer[] index = (Integer[])( treeMap.keySet().toArray( new Integer[treeMap.size()] ) );
for (int i = 0; i < index.length; i++) {
device = new JSONObject();
device.put("device_name", treeMap.get(index[i]).getLocation());
device.put("state", treeMap.get(index[i]).getDeviceStatus());
// device.put("shift_register", this.toArduinoShiftRegisterCode());
// System.out.println(index[i]);
deviceList.add(device);
}
json.put("deviceList", deviceList);
return json.toString();
}
public boolean hadSerialAnswer() {
return serialAnswer;
}
public void setSerialAnswer(boolean serialAnswer) {
this.serialAnswer = serialAnswer;
}
public String getFeedback() {
return feedback;
}
public void setFeedback(String feedback) {
this.feedback = feedback;
}
public SerialAnswerMonitor getSerialMonitor() {
return serialMonitor;
}
public void setSerialMonitor(SerialAnswerMonitor serialMonitor) {
this.serialMonitor = serialMonitor;
}
}
继续使用SerialAnswerMonitor它的无限循环。
public class SerialAnswerMonitor {
public SerialAnswerMonitor() {
this.generator.start();
}
private final Thread generator = new Thread("Serial Answer Monitoring") {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
//Get the device monitor so it can get device states
DeviceMonitor deviceMonitor = (DeviceMonitor) envCtx.lookup("states/DeviceMonitorFactory");
if (deviceMonitor.hadSerialAnswer()) {
String feedback = deviceMonitor.getFeedback();
for(Map.Entry<Integer, Device> entry : deviceMonitor.getStatesTreeMap().entrySet()) {
Device value = entry.getValue();
if (value instanceof RfCoded && ((RfCoded) value).getFeedbackId().equals(feedback.toLowerCase())) {
System.out.println(Notifications.NOTIF_SWITCHING_VIRTUAL_STATUS);
if (!value.getDeviceStatus() && Character.isUpperCase(feedback.charAt(0))) {
((RfCoded) value).switchStatesFromFeedBack();
} else if (value.getDeviceStatus() && Character.isLowerCase(feedback.charAt(0))) {
((RfCoded) value).switchStatesFromFeedBack();
}
}
}
}
} catch (NamingException e) {
System.out.println(Notifications.EXCEP_DEVICEMONITOR_CONTEXT + "(Serial Answer Monitoring)");
System.out.println("Killing [" + Thread.currentThread().getName() + "] thread to stop exception propagating.");
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
}
};
}