Java inter-thread communication and feasibility - java

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 :)

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.

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 !

Related

Other ways to perform tasks without loops?

I'm fairly new to java and I was creating a program which would run indefinitely. Currently, the way I have the program set up is calling a certain method which would perform a task then call another method in the same class, this method would perform a task then call the initial method. This process would repeat indefinitely until I stop the compiler.
My problem is when I try to create a GUI to make my program more user friendly, once I press the initial start button this infinite loop will not allow me to perform any other actions -- including stopping the program.
There has to be another way to do this?
I apologize if this method is extremely sloppy, I sort of taught myself java from videos and looking at other programs and don't entirely understand it yet.
You'll need to run your task in a new thread, and have your GUI stuff in another thread.
Actually, if you keep working on this problem, you'll eventually invent event driven programming. Lots of GUI based software, like Android, use this paradigm.
There are several solutions. The first that comes to mind is that you could put whatever method needs to run forever in its own thread, and have a different thread listen for user input. This might introduce difficulties in getting the threads to interact with each other, but it would allow you to do this.
Alternatively, add a method that checks for user input and handles it inside the infinite loop of your program. something like below
while(true){
//do stuff
checkForUserInput();
//do other stuff
}
To solve this problem, you need to run your UI in another thread.
Many programs are based on an infinite loop (servers that keep waiting for a new user to connect for example) and your problem isn't there.
Managing the CPU time (or the core) allocated to your infinite loop and the one allocated to take care of your UI interactions is the job of the operating system, not yours : that's why your UI should run in a separate thread than your actual code.
Depending on the GUI library (Swing, ...) you're using there may be different ways to do it and the way to implement it is well answered on Stack Overflow

Concurrency for objects in Java

I am currently working on an exercise in which I have to design a small and simple industrial factory in Java. Basically I've got a warehouse for storage, machines that produce stuff and a GUI that takes commands and informs the user of the current stockpile of the different products, etc.
I've got almost everything working, however, with the limitation that only one machine can produce at a time right now. This is probably due to my approach to the whole exercise. I wanted to start small and just coded tiny units of the program that could work independently and then pieced them together one after another adding more and more logic to the application and implementing all the communication between the different classes, etc.
Now I am at the point where everything seems to be fine and the only thing left to do is to establish concurrency so that I can run several machines at the same time without any problems.
To give you a better understand, I'll try to outline my applications structure:
First there's a GUI and a GUI Controller that assigns the tasks wanted by the user to the other Controllers in the application. It also manages the updates for the GUI (stockpile, ...)
Then I've got the warehouse section with the actual warehouse (HSQLDB, file based, JDBC connection) and a storageController, which controls all tasks regarding the warehouse (store products, remove products, get the stock, ...)
And finally there is the machine section.
There are 3 types of machines. Each type differs only in the product produced. Type 1 and 3 produce the raw products needed for type 2 to produce a final product.
In order to create as many machines as one likes to, I decided to use a Abstract Factory pattern to implement them. That means that I've got an abstractMachineFactory, which holds all the needed attributes (like a machine ID, its status (on/off), ...) and methods including an abstract method "produce(boolean status)". Status = true means that the machine is producing, false means that it's not.
I gave each of the machine types its own class, so that I've got concreteMachineType1, concreteMachineType2 and concreteMachineType3. In there the "produce()" method is implemented specifically to the machine type, i.e. type2's method checks (via the machineController) if there is a big enough stockpile of the raw products that type1 and 3 produce so that it can begin producing.
As the machines should be continually producing, the body executes "while (status=true)". If the stockpile is not big enough, the machine will check again after a certain timeout (via the controller).
And now we come to the machineController. This controller manages all tasks regarding the individual machines. That means creating them, starting/stopping a single or all machines, get supplies from the warehouse, bring the final product from the interim storage to the warehouse, etc.
In order to identify and access my machines, I've implemented different array lists (one for each machine type) in which the machine objects are stored, with the index of the array being the machines' ID. This way I can start/stop a specific machine by accessing the index or start/stop all by parsing through the whole array list.
When starting the machines I also execute the "produce()" method and this is where the problem is at the moment (in my opinion).
This is what happens: I create a few new machines (default is that they are turned off) and then execute my startAllMachines() method. What this method will do is parsing through the array list and executing startMachine() on every single machine object in that list. As said above, startMachine() also calls the produce() method of the machine.
And now I'm basically in an infinite loop, as the produce() method of that machine will run as long as I turn it off, by setting its status value to false. That means that all other machines will not be turned on, so that only this single machine will produce and the rest is in a queue that will never be reached.
I figure that I need different threads to work all machines concurrently, so that each machine is started by a different thread. The problem is that I have no clue on how to achieve this and the basic tutorials I've found didn't help me either. Most of them suggested implementing Runable() and defining a run() method, but this isn't applicable in my scenario (imho). What I think I need is concurrent machine starter objects or something.
I hope some of you can give me hints in how to proceed here.
best regards
daZza
class Machine {
private Thread producerThread;
/**
* Non blocking method that produces fixed amount of stuff and returns.
*/
private void produceStuff() {
// TODO
}
private void startProducing() {
Runnable producingTask = new Runnable() {
public void run() {
produce();
}
};
producerThread = new Thread(producingTask);
producerThread.start();
}
private void stopProducing() {
if (producerThread != null) {
producerThread.interrupt();
}
}
/**
* Check cancellation every time stuff is produced.
*/
private void produce() {
while (!Thread.currentThread().isInterrupted()) {
produceStuff();
}
}
public void start() {
startProducing();
}
public void stop() {
stopProducing();
}
}

When I must stop my actors?

I start my actor in controller in Play 2. I read somewhere that I must stop my actors. When I stop it as in example below I got the problem that file do not upload at all. When I comment it starts uploading it.
//Akka
ActorSystem system = Akka.system();
ActorRef uploader = system.actorOf(new Props(UploaderActor.class), "uploader");
uploader.tell(new Uploader(post.id, "/public/images/post/",post, request()), uploader);
//system.stop(uploader);
Please help.
My question is: When I must stop my Actors?
One additional question:
How can I access this actor in another controller(get this reference) ?
I'd suggest to create a long-lived uploader that you send the upload-messages to, and it can internally create new actors to handle the actual uploads and shut them down if need be. This frees the client, you, from managing the life-cycle.
If this actor is meant to be short lived and only process a single request, then you can have the actor stop itself in the receive method after it's done like this:
getContext().stop(getSelf());
That way you can be sure the actor is done before being stopped. For your second question, if you want to look up this actor instance from somewhere else, all you need is a reference to the actor system that it is running in. If you have that then it's just:
ActorRef ref = system.actorFor("/user/uploader")
If you are going to be spawning multiple uploaders at a time then be sure to name them uniquely. The name you give it when starting it is the name you can use to look it up from some other piece of code.

Detect where in the process we are in?

I have an interesting question if someone can help me to think up a solution.
I spawn 2 separate processes, A and B. Think them as a Queue waiting for work
A is being filled and do something
A is done and pass onto B
B do something and finish
How do I detect where in the process we are in using Java? And how I would stop this process where ever we are at?
Thanks!
In pure Java, you would have memory variables that are accessed by both threads, so they can communicate. You would need to make them synchronized or use semaphores to make sure only one thread at a time is modifying the information in the variable.
Other languages have the concept of actors, which implement more robust inter-thread communication by passing messages. Look into Scala - it's built on top of Java. Or the akka library, which has Scala and Java versions.
If you like thinking about this stuff, try the book Seven Languages in Seven Weeks by the Pragmatic Programmers.
you can add a currentStage variable and update stage at different locations in your code. Also save your "registers". By this I mean save your local variables that you care about. Serialize objects and perhaps place them in a database.
Then if you quit and restart, you go to the last saved stage and restore the corresponding objects from the database.
To follow the process you would need another Thread (C) that can read status information outputted by A & B and that can be asked by A & B if they should continue.
For instance, create a ProcessFollower interface with 2 methods:
void updateStatus (String)
boolean shouldStop ()
C can implement this interface and pass itself when calling A, A passed the reference to ProcessFollower (C) to B. Each time the status changes A and B call updateStatus and on each occasion (e.g. each loop iteration) they check shouldStop(); if false they simply return or such.

Modeling asynchronous game-like environment

The idea is to model an environment for agents. In the most basic case it looks likes this:
System asks the agent for the next action
Agent responds (e.g. "move left!")
System moves the agent to the appropriate state
However, I am having trouble implementing this in an asynchronous manner (with threading and such).
Currently my system looks like this:
void Start(){
while(true && !gameOver){
askAgent()
moveAgent()
if(agentState == terminalState){
gameOver = True;
}
}
}
Clearly, this blocks the thread this is running on.
(What's more embarrassing is I am using OSGi, so any single bundle should not be hogging all the processing time!)
Also, I would like the system to react to new agents appearing in the environment, and engage with them (my runtime, OSGi, already has the facility of notifying me if something appears or disappears from the system) something like:
void setAgent(Agent agent){
system.addAgentToEnvironment(agent);
system.simulateAgent(agent);
}
Instead of just running from main straight away...
I know this is very confusing, and I am not sure if I am even posing the question correctly - so any tips on the architecture or approaches I can look at are greatly appreciated.
You will definitely need some data protection (perhaps on a master list of agents, and some kind of protection on each individual agent and its data).
Other than that, I would follow this kind of model:
while (waiting for events)
spawn thread to respond to event // add agent, calculate and perform move, etc.
// even better would be to enqueue the event into a thread pool
if (terminal)
break // end game
HTH
In order to help think about the future of the application, I would urge you to use two loops.
long then = System.currentTimeMillis();
for(Agent a : agents) {
agent.calcuateNextMove(getEnvironment());
}
for(Agent a : agents) {
agent.performNextMove(getEnvironment());
}
long now = System.currentTimeMillis();
sleep(TIME_STEP_DURATION + now - then); // give you a steady frame rate in relation to real time
This snippet gives you two things.
Moves are made independently of other moves on the same step. This way you do not have your current move influenced by those who happened to move before you.
An agent merely exists, and is simply told to calculate his next move based on the environment you give it. This makes it incredibly easy to change states, copy agents into multiple environments, and give the illusion that the environment is different than it really is. For example, you may have a filterFor(Environment e, Agent a) that makes a mocked up version of the environment for that particular agent. Like wearing drunk-goggles or a blindfold or something.

Categories