进程间通信以共享Java中数据的更新

时间:2016-09-11 16:09:16

标签: java ipc data-synchronization

我正在创建一个带传感器的令牌环。我在SensorClient类中定义了客户端进程。这些客户端对象从服务器进程createSensor类接收有关其他客户端列表的信息。

问题是我希望客户端更新服务器上更改时的信息。

服务器类:

    public class createSensor {

                private static createSensor instance = null;
                private ArrayList<Sensor> sensor = new ArrayList<>();
               public int position, prevPosition, nextPosition, prevPort, nextPort;

                    private createSensor() {
                    } 
 public synchronized ArrayList insertSensor(String type, String identificator, int port, String id, String gatwayAddr, long timestamp) throws IOException {

            sensor.add(new Sensor(type, identificator, port, id, gatwayAddr, timestamp));
            return new ArrayList<>(sensor); // 
        }
    }
    public synchronized boolean hasMeasurements() {
        while (InnerBuffer.getInstance().emptyInnerBuffer())
            return false;
        return true;
    }


    public synchronized void setPrevNextWhenDelete(int position,ArrayList<Sensor> sensorList) throws IOException {
//code

    }

    public synchronized ArrayList<Sensor> getSensorList() {
        return new ArrayList<>(sensor);
    }

    public synchronized int size() {
        return sensor.size();
    }

    public synchronized String returnRecentMeasurement (String id){
        String recentMeasurement=null;
        for (Sensor sensori : sensor) {
            if (sensori.getIdentificator().equalsIgnoreCase(id))
               recentMeasurement= InnerBuffer.getInstance().returnRecentMeasurements(id);
            else
                recentMeasurement = null;}
        return recentMeasurement;
    }
                public synchronized void  setPrevNextWhenAdd() throws IOException {  //some other code where int position, prevPosition, nextPosition, prevPort, nextPort get their values.


              }}

客户端类:

public class SensorClient {
                public static void main(String[] args) throws Exception {
                    //Starting a new sensor
         Sensor sensor = new Sensor(type,identificator,portnumber,ipnumber,gatewayAddr,timestamp);
            Gson gson = new Gson();
            String message = gson.toJson(sensor);
            Client c = Client.create();
            WebResource r = c.resource("http://localhost:9999/gateway/");
            ClientResponse response = r.path("sensors/add").type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).post(ClientResponse.class, message);
            if (response.getStatus() == 200) {
                repeat = false;
                Type collectionType = new TypeToken<ArrayList<Sensor>>(){}.getType();
                ArrayList<Sensor> sensorList = gson.fromJson(response.getEntity(String.class), collectionType);
                System.out.println("Starting the sensor ...");
                System.out.println("Push exit when you want to delete the sensor!");
                int position = 0;
                for(int i = 0; i< sensorList.size();i++){
                  if(sensorList.get(i).getIdentificator().equalsIgnoreCase(sensor.getIdentificator()) )
                        position = i;
                }

                sensors.Sensor.simulation(type, identificator);// special thread for sensors simulations
                 createSensor.getInstance().setPrevNextWhenAdd(position,sensorList);
                serverSocket serverSocket = new serverSocket(portnumber,sensorList,position,sensorList.get(position).getNext());
                serverSocket.start();

                StopSensor stopSensor = new StopSensor(identificator,portnumber,position,sensorList);
                stopSensor.start();

                   oneSensor s = new oneSensor(portnumber,sensorList);
                    s.start();
              } else {
                repeat = true;
                count +=1;
                System.out.println("Error. Wrong data! ");
            }
          }
        while (repeat );
    }
}
                        }

serverSocket线程

public class serverSocket extends Thread {
    public int port,nextPort;
    ArrayList<gateway.Sensor> sensorList;
    public static int position;
    public serverSocket(int port, ArrayList<gateway.Sensor> sensorList,int position,int nextPort) {
        this.port = port;
        this.nextPort=nextPort;
        this.sensorList= sensorList;
        this.position=position;}
    public void run() {
            ServerSocket welcomeSocket;
            Socket connectionSocket;
            try {
                welcomeSocket = new ServerSocket(port);
                while (true) {
                    connectionSocket = welcomeSocket.accept();

                    receivedMessages thread = new receivedMessages(connectionSocket,sensorList,position,nextPort);
                    thread.start();
                }
            } catch (IOException e) {
                e.printStackTrace();
                System.err.println("Error!!!!!!!!!");
            }
        }
}

receivedMessages线程

public class receivedMessages extends Thread {

        private BufferedReader inFromClient;
        private Socket connectionSocket;
    ArrayList<gateway.Sensor> sensorList;
    int position,nextPort;
        public receivedMessages(Socket socket, ArrayList<gateway.Sensor> sensorList,int position,int nextPort){
            connectionSocket = socket;
            this.sensorList=sensorList;
            this.position=position;
            this.nextPort=nextPort;
           try {
                inFromClient = new BufferedReader( new InputStreamReader(connectionSocket.getInputStream()));
               } catch (IOException e) { e.printStackTrace(); }
            }
            @Override
        public void run() {
                //  while(true) {
                try {

                    String message = (inFromClient.readLine().toString());

                    System.out.println(message);
                    if (message.startsWith("Next") || message.startsWith("Previous")) {
                        System.out.println(message);
                    } else if (message.startsWith("The")) {

                        System.out.println(message);                        createSensor.getInstance().setPrevNextWhenDelete(position, sensorList);
                    } else  {// i receive the message that the list has changed
                    System.out.println(message);
                    sensorList = createSensor.getInstance().getSensorList();
                    System.out.println("Updated " + sensorList);}

1 个答案:

答案 0 :(得分:0)

倾听变化

在修改数据时,有两种方法可以通知您的客户端进程:

  • 您的客户端对象可以定期检查列表是否已被修改:

    • 通过询问列表的当前版本
    • 或者通过询问列表修改的时间戳(您的服务器类createSensor,然后必须保留该记录)
  • 您的客户端对象可以打开一个端口来监听通知,您的服务器类可以通知他们更改,在修改列表时将新列表推送给他们。

在侦听器线程和工作线程之间共享更新

在这两种情况下,在您的客户端,您将有一个线程正在完成工作,另一个线程正在侦听更改。第二个线程每次都会重建一个新列表。为了与工作线程共享,您可以执行以下操作:

  • 您的侦听器线程将保留对创建时工作线程先前传递的sensorList的引用
  • 重建新列表时,您的侦听器线程会将该新列表存储在另一个引用newList
  • 然后,您的侦听器列表可以使用oldList.clear()然后oldList.addAll(newList)修改“旧”列表,使其与新列表匹配。

这样可行,因为即使工作线程可能有自己对列表的引用,两个引用都指向同一个对象,因此它会看到更改。

启动侦听器线程的代码

例如,如果您的工作线程是主线程,并且它正在创建侦听器线程,那么您的代码可能就像在工作线程代码中一样:

class Listener implements Runnable {

   List<Sensor> sensorList;
   Listener(List<Sensor> list ){
      sensorList = list;
   }

   public void run(){
      // code to listen to changes on the server
      // When server sends new information, thread can update the list directly:
      // sensorList.clear();
      // sensorList.addAll(newList);
   }
}

Listener l = new Listener(sensorList);
Thread listenerThread = new Thread(l);
listenerThread.start();

您可以在Java Tutorials on Concurrency中阅读有关线程及其共享内存的方法。

请注意同步:当您更新旧列表时,您应该确保其他线程没有迭代它。您应该使用Collections.synchronizedList(sensorList)来确保没有线程干扰。