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();
}
}
Related
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 !
I created a GUI Application in JavaFX which communicates with a serial device (I use a jssc connector). When I want to get data I send a communicate, then wait 1s until the wait function terminates. Communicate is also being sent, among other things, when I click one of the buttons (for starting a device, for identification, etc.). During development process I noticed a bug - communication hangs (but only when receiving messages, I still can send one-way communicates for ie. starting a device) when I click too many buttons too fast or I click buttons which send more than one communicate.
Communication is mainly handled by my own class SerialPortDevice. I create an object of a class' type and then invoke particular methods. Here's the method which waits for a message:
private String waitForMessage() throws SerialPortException {
long operationStartTime = System.currentTimeMillis();
long connectionTimeout = SerialPortCommunicationParameters.CONNECTION_TIMEOUT_IN_MILLIS;
String resultMessage = "";
do {
if (readEventOccurred) {
System.out.println();
resultMessage = receiveMessage();
System.out.println("After receiving a message");
messageReceived = true;
}
} while (((System.currentTimeMillis() - operationStartTime) < connectionTimeout) && (!messageReceived));
if (!readEventOccurred) {
resultMessage = NO_RESPONSE;
}
System.out.println("Time elapsed: " + (System.currentTimeMillis() - operationStartTime + "ms"));
return resultMessage;
}
One can notice that message is being received only when a flag readEventOccured is true. It's handled by my implementation of the SerialPortEventListener:
class SerialPortDeviceReader implements SerialPortEventListener {
private SerialPortDevice device;
SerialPortDeviceReader(SerialPortDevice device) {
this.device = device;
}
public void serialEvent(SerialPortEvent event) {
if (event.isRXCHAR()) {
System.out.println("Serial Event Occured!");
device.setReadEventOccurred(true);
}
}
}
readEventOccured is a boolean field in the SerialPortDevice class which contains waitForMessage function. Also, waitForMessage is invoked by another function, singleConversation:
String singleConversation(String testMessage) {
String resultMessage = NO_RESPONSE;
try {
openConnection();
sendMessage(testMessage);
resultMessage = waitForMessage();
closeConnection();
} catch (SerialPortException e) {
e.printStackTrace();
return resultMessage;
}
System.out.println();
readEventOccurred = false;
messageReceived = false;
return resultMessage;
}
... Which is the only function setting readEventOccured to false. And it is a "top level" function in a SerialPortDevice class which handles sending and receiving a communicates to and from a device.
So communication looks like this:
Button click -> Button handler invocation -> device.singleCommunication(buttons_specific_communicate) -> some methods run and then it comes to the waitForMessage -> method waits 1s for the event -> event occurs (everytime - I get the "Serial Event Occured" communicate) -> readEventOccured is being set to true -> if there is some time left (there is always some time left, everything lasts a miliseconds), message is being received in the waitForMessage method.
There is no problem if I click buttons with a short (in a human sense, 2-3s for example) delay or I don't click these which do send more than one communicate inside their handlers. In different situations weird things happen. I still get the message "Serial Event Occured" (so I suppose readEventOccured is also being set to true) but waitForMessage function does not execute
if(readEventOccured)
statement's code. Also, I have to run an application again to be able to communicate with a device (I mean receiving data, sending works perfectly).
What solved my problem was adding "volatile" modifier to the readEventOccured flag (makes sense by the way, things go fast sometimes). But it didn't please me. I wanted to make a code to run correctly without "volatile". My coworker came up with an idea something goes wrong with threads that are being created when I click buttons and invoke communication - maybe something blocks other thing somewhere? First thing I did was to print all the currently runnig threads and... Man, it solved a problem. App was not hanging anymore. Really, I performed "hanging" scenarios 10-20 times with and without
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
System.out.println(threadSet);
at the beginning of the waitForMessage method and result were unambigous - it somehow removed my problem.
I'm almost certainly sure getting and printing threads is not a solution itself. It's something that is being done by the way but I can't find out what is this. Any useful information? Maybe better understanding Threads in Java would help me? Or it is something else?
Cheers
What you're doing is the textbook example of what happens when there are no visibility guarantees. If we distil your code into its essential bits, we get something like this:
boolean flag = false;
void consume() {
while (true) {
if (flag) {
//we received flag, hooray
}
}
}
void produce() {
flag = true;
}
Now, if produce() and consume() run in different threads, there is absolutely no guarantee that consume() will EVER see flag set to true. volatile creates a memory barrier, meaning that all reads/writes of those variable will be fully ordered.
What you also have in the code though, is lots of System.out.println() lines. These complicate the picture, as they themselves are synchronized, and thus create happens-before relationships between different parts of the code. Unfortunately they don't create the correct sequence, but poke in a few more and you can accidentally get it right. The key word here is "accidentally", you shouldn't rely on this behaviour at all.
So marking readEventOccurred as volatile sort of fixes the problem but going a bit further we can see that your waitForMessage() spin-waits, which is rarely a good idea. I would take a look at the CountDownLatch class for example, designed for similar scenarios. (An even better candidate is its close friend, CyclicBarrier.)
What solved my problem was adding "volatile" modifier to the readEventOccured flag (makes sense by the way, things go fast sometimes). But it didn't please me. I wanted to make a code to run correctly without "volatile".
The fact that adding volatile fixes the problem indicates you've run into the lack of guarantees by the Java Memory Model when multiple threads are involved. Simply put there is no guarantee of when a change on one thread is visible on other threads except for specific situations.
The probably reason why printing 'fixes' the problem is the fact that it:
Changes the timing of the program, might mean the situation in which it fails no longer exists.
Temporarily suspends the threads to read out their current state, maybe the JVM also uses that as an opportunity to synchronize memory.
Multithreaded communication is hard, so I recommend you take a look at the classes available in java.util.concurrent, which have guarantees that you might be able to use to solve your problem more elegantly.
I must say that I'm new to Java and JavaFX (less than 2 months), and also my UML skills are not perfect, so I might have used wrong blocks or/and connectors on the diagram :) But I hope you get an idea.
I have an order management app with a following (simplified to essentials) design:
OMS app design
Put very simply, the JavaFX GUI displays in a table view what is happening (i.e. the current state of the orders) between the client (that sends orders) and the broker (on the other end of the network connection). Order Manager is the only entity that has access to modify the model (i.e., the list of orders and their fields), and all methods modifying the model are synchronised (so it's safe to call them from any thread).
The orders are JavaFX beans, with different fields implemented as JavaFX Properties. These properties are bound to table columns in the GUI, so whenever the Order Manager updates a field, the change is propagated to the GUI via the binding mechanism.
Now, because the property binding mechanism is not thread-safe (see the following rule:
An application must attach nodes to a Scene, and modify nodes that are already attached to a Scene, on the JavaFX Application Thread.
), I have to wrap all the code modifying those fields, in Platform.runLater() calls, for example:
public void onOrderCanceled(int id, String reason) {
Order order = orderbook.get(id);
if(order == null) {
throw new IllegalArgumentException("Order "+id+ " not found");
}
Platform.runLater(() -> {
order.setReason(reason);
order.setStated(CANCELED);
subscribers.foreach(sub -> sub.notifyUpdated(order));
});
}
This approach has the following unpleasant implications:
The client notification is delayed by an arbitrary time (till the GUI thread finishes processing its message queue). Reason: I cannot notify the client before the order fields are updated (or it will have incorrect data), and I can only update the fields in the GUI thread.
Because the state of the order is not modified right away but at some future point, there exists for some time an incoherence between the order object and the actual order state.
If the GUI thread gets blocked or becomes very slow (because of bugs or design flaws), the client code is blocked or slowed down (while waiting for the notification that is stuck in the GUI thread's message queue).
Is there a better way of doing that? Ideally, I would like a solution that:
Allows the client code to communicate with the networking layer (via the order manager) as fast as possible, i.e. without waiting for the GUI to catch-up
The GUI is allowed to lag behind a little bit, but must not "skip" field updates, or at least never drop the most recent update (which is the most relevant)
Rely on the FX property binding architecture to update the GUI (which I find very convenient)
I feel that I need to create another "model" for the GUI that will be updated in the FX thread only, while the "real" model will be used by the order manager and the client code, and I need to ensure to maintain the two models in sync (which is creepy).
Was FX designed without multithreading in mind? I had a look on the Task and Service interfaces, but is doesn't look like something appropriate (in my case, GUI doesn't initiates a task - it comes from an external source, the client code or the network).
Thanks in advance!
If I understand this implementation correctly, you are performing the notification to remote clients on the FX Application Thread. You're doing this because you need to send the clients the updated version of the Order object, and since this object is bound to the table, changes to its state can only happen on that thread.
This is somewhat perilous, as those remote notifications may take time, and so you may block the UI thread, causing a lack of responsiveness. Additionally, you are forcing the logic of the application to wait for the (potentially blocked) UI thread. This is the opposite way around to the way you should be doing things: your application logic should flow in a thread of execution in a natural way, and you should arrange for the FX Application Thread to show the latest version of the data in as lightweight a way as possible on each frame rendering.
I think what you need here is a separate, immutable class to represent the updates. You'll send those to your clients, and then on successful notification update the UI, instead of driving the application from the UI. So something like
public abstract class Update {
private final int orderId ;
public Update(int orderId) {
this.orderId = orderId ;
}
public abstract void performUpdate(Order order) ;
public int getOrderId() {
return orderId ;
}
}
and
public class Cancelation extends Update {
private final String reason ;
public Cancelation(int orderId, String reason) {
super(orderId);
this.reason = reason ;
}
public String getReason() {
return reason ;
}
#Override
public void performUpdate(Order order) {
if (order.getId() != getOrderId()) {
throw new IllegalArgumentException("Wrong order");
}
order.setReason(reason);
order.setState(CANCELED);
}
}
Now in your application code you can do something like
public void onOrderCanceled(int id, String reason) {
Order order = orderbook.get(id);
if(order == null) {
throw new IllegalArgumentException("Order "+id+ " not found");
}
Task<Update> updateTask = new Task<Update>() {
#Override
public Update call() throws Exception {
Update update = new Cancelation(id, reason);
subscribers.forEach(sub -> sub.notifyUpdate(update));
return update ;
}
};
updateTask.setOnSucceeded(e -> updateTask.getValue().performUpdate(order));
updateTask.setOnFailed(e -> {
Exception exc = updateTask.getException();
// handle exception
});
subscriberNotification.execute(updateTask);
}
Now you schedule updates in an executor dedicated to that particular functionality, and then update the UI when you know the notification has happened. In other words, the UI responds to the application logic, instead of the other way around. Your clients now receive the details of the update, and presumably they have their own representation of the Order (perhaps instances of the same class), and can update their own representations using the information in the Update. Note this will likely save you network traffic too (probably the biggest bottleneck in your application), because you only communicate the changes, instead of the entire object. Of course, this might entail some major refactoring of your code (sorry about that...).
It's going to be important that the updates are all transmitted in the correct order, so you should use a single thread of execution for managing them. In other words, you need something like
private final Executor subscriberNotification = Executors.newSingleThreadedExecutor();
All,
I have appreciated many helpful answers on this site but I have found a need to post my first question (if you notice anything to be improved in my post let me know).
I have a modest sized Java program with GUI that is acting as a "middleman" and controller. On one end of the information flow it sends and receives data via an HTTP server. On the other it is interacting with an API where data is ultimately exchanging with a SmartCard. In the "middle" is the GUI, logging, and some other features.
There is also a feature (initiated via the GUI) to occasionally load an update to the SmartCard. Otherwise exchanges with the SmartCard are initiated over HTTP.
The problem is when switching between these 2 modes (communicating http to smartcard and then switching to loading the update or vice versa).
When I do that I have concluded I run into the problem of
CardException: Exclusive access established by another Thread
as thrown by sun.security.smartcardio
Searching the web shows the code that exception appears to come from is
void checkExclusive() throws CardException {
Thread t = exclusiveThread;
if (t == null) {
return;
}
if (t != Thread.currentThread()) {
throw new CardException("Exclusive access established by another Thread");
}
}
My first thought was I needed to instantiate the SmartCard API each time I need it (and then set it back to null) instead of once for the entire program like I had initially.
This works for the exchanges over http and I figure it is because each request to the handle() method is a new thread.
In the GUI the update is initiated by an ActionEvent which makes an instance of a CardUpdate. Inside that class then gets an instance of the SmartCard API.
I thought maybe I'd have better luck if when actionPerformed triggered I put the actions on a different, temporary, thread. So far, no.
The closest I got was using something like:
SwingWorker worker = new SwingWorker<ImageIcon[], Void>() {
as found at on Sun's website
Using that I could do an update and then go back to http exchanges but I couldn't do another update (per the one time use stipulation of SwingWorker)
I then tried making multiple SwingWorker as needed doing something like
private class GUICardUpdate extends SwingWorker<Integer, Void > {
but then I was back to my original problem. I have also tried to just do a simple additional thread off the GUI class in this fashion:
public class GUI extends javax.swing.JFrame implements ActionListener, Runnable
but this is no different.
Maybe I don't understand threads well enough or maybe I am overlooking something simple. Anyone have any ideas?
Thanks!
As far as I got you are using javax.smartcardio package (directly or indirectly) to work with your card. Some thread (created by you or by the framework you are probably using on top of javax.smartcardio) invoked beginExclusive() method on the Card instance to ensure exclusive access to the card.
The exclusive access is necessary as treatment of the data kept on the IC cards is state-depended, so the proper selection of data files and reading of their records requires the actions of application layer not to be interfered with actions of some other application or thread. For this purpose these three Card interface methods beginExclusive(), endExclusive() and checkExclusive() exist.
So you should check your(framework) code if it calls beginExclusive() and then doesn't call endExclusive().
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.