Servlet中无限循环的良好实践

时间:2013-11-25 01:51:28

标签: java servlets while-loop infinite

我有一个线程必须在无限循环中进行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();
            }
        }
    }
};

}

0 个答案:

没有答案