0

First, to shortly describe my problem. Based on the simbad simulator ( http://simbad.sourceforge.net/doc.php - not important for my question ), I want to build a system that deploys rovers which will explore the environment. The idea is that these rovers will avoid obstacles in the environment as well as other rovers. Let's call this a simulation. The main elements in this simulation are of course the rovers, the environment, and a central station which will control the rovers and also send commands to it. This will run on a thread.

What I would like to have, is on another thread/process, to have a listener. This will listen to commands inputted from the keyboard and translate them into commands that will be applied in my simulation by the central station. For example, each rover might have an ID, and I might want to remove a remover based on its id. Then I'd like to write something like: remove rover 1, the listener that is running on another thread maps this to a command and for example calls the function centralStation.removeRobot(id_of_robot).

What is the best way of implementing this ? Basically I will have 2 threads, one running the simulation, one listening to commands, and the centralStation should be a shared resource ? How do I make it a shared resource (make a main, initiate the central station, then call the other 2 threads to start doing their job? ) ?

I was wondering what the best practices for this is, and how to make it as simple as possible. Thank you :)

  • Let existing Java tools handle the threading for you; use things like [key listeners](https://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html) instead. Then you only need the one main thread and don't need to deal with locking etc. – Luke Briggs Feb 23 '17 at 12:27
  • Also StackOverflow isn't designed for these kinds of _"is x possible? How do I do it?"_ questions - this community is for helping you out with an issue with an algorithm/ code etc instead. Your question was well written though, so kudos for that :) – Luke Briggs Feb 23 '17 at 12:30

2 Answers2

0

A simple solution is to simply put an appropriate data structure "between" your components.

For example an instance of ConcurrentLinkedQueue. The idea here: your "input" thread writes "command" objects into that queue; and the other thread looks into that queue, and when it finds a new command, that is "applied" to the simulation.

The important aspect is: you really do not want that two threads are operating on the same data somehow.

Community
  • 1
  • 1
GhostCat
  • 137,827
  • 25
  • 176
  • 248
0

Well how about Java Exchanger, where String is the id of rover/command that your listener would transfer to central station https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Exchanger.html

If I am understanding it correct then you want to start the system and at runtime pass the rover id/command, after processing it via a Listener(which would be in a separate thread), to the central station(which would be in a separate thread).

So how I might have proceeded with this would be: In main thread, start the simulator, Create an Exchanger, and start two threads, one for central station and another for listener.

    // pseudocode for main
    main() {
        // start simulator ( I am not sure what this thing is)
        Exchanger<String> exc = new Exchanger<String>();
        new CentralStationThread(exc);
        new CommandListenerThread(exc);
    }

Now in CentralStationThread one of the first thing that you might wanna do is register with the listener

    //pseudocode for run method of central station
    public void run(){
        String roverIdToStop = exc.exchange(new String);
        // some code to trigger the rover stop
        // send in replacement rover
    }

And something similar in CommandListenerThread thread, but not at start

    //pseudocode for run method of listener
    public void run(){
        // Listen to keyboard
        // String roverIdOrCommand = Parse the command & make something out out it
        // when the command is ready to be sent to central station do following
        String roverIdToStop = exc.exchange(roverIdOrCommand);
        // keep looking for further commands
    }

I agree, There might me several ways to achieve the same but this is what came to my mind. Hope it helps !

Mayank
  • 188
  • 3
  • 6