Updating UI when variable changes - java

I have about 50 variables that get updated with an rate of about 1kHz by network, but their values change only every few seconds.
The values are for the UI (e.g. text, visibility and background color for buttons).
What is the most efficient way to update the UI?
I previously runned a task every 100ms on the UI thread that set all UI variables. The problem for me was the jitter of the other tasks every 100ms.
I'm looking for a solution to update the UI only when the variables changes.
Is there another way than implementing an own 'variable changed' listener?

That is a common problem in computer science and has been already solved by the Gang of Four. Use the Observer/Observable pattern to recognize changes. Android has also some built in modules that implement MVC (Adapters and ListViews...).

I believe that implementing a "variable changed" listener is probably the most correct (and most efficient) way to implement this, but you could always compare the value currently displayed in the UI to the value updated on the network prior to changing the UI.
if(!label.getText().equals(networkVal)) {
label.setText(networkVal);
}
I think something like that would work with the system that you described and reduce the jitter.

You might want to consider using setter methods for your variables and updating your widgets inside these methods.

I previously runned a task every 100ms on the UI thread that set all UI variables. The problem for me was the jitter of the other tasks every 100ms.
Then split the updating into ten parts and run every 10 ms one part.
From another answer:
you could always compare the value currently displayed in the UI to the value updated on the network prior to changing the UI.
I would not do it. This means to access the components often and getting their value may be expensive and complicated as they belong to the AWT-Thread. If your model contains an int, then getting the value back from the GUI may include parsing, which needlessly slows it down.
I keep the .getText().equals() in a normal thread.
This would work if this very thread was the only one updating the value. Which is not true as you should do all the updates on the AWT Thread. This could lead to problems.
The simple solution is:
Maintain a copy of the variables.
From time to time compare a few variables against the copy (so that in total every 100 ms all variables get checked).
When there are any differences, update the GUI (using SwingUtilities.invokeLater) and update the copy (normally).
The Observer Pattern is the nicer but much more verbose solution.

You can try to use either websocket or long polling.
What are Long-Polling, Websockets, Server-Sent Events (SSE) and Comet has a good discussion.

Related

Can I do Swing operations at shutdown time?

This relates to this Java question.
Here's my problem. I've written an app that allows people to do a lot of data entry, typing into a lot of separate fields. To confirm the change in each field they can often hit Return (for a single line field) or control-S (for multi-line fields where Return would be valid input), but that's cumbersome, so I also allowed fields to save their content when they lose focus. So users can type-tab-type and it all goes smoothly.
Except if they change a field and then click on the application window exit X in the corner. They expect that this counts as losing focus and will save that last change. But the lost focus event doesn't happen and the change is lost.
I could add a Done button, which would have the side effect of moving focus and saving the last field, and then exiting. But I shouldn't have to. There's a X in the corner and it should do the right thing.
My first thought was
frame.addWindowListener(new java.awt.event.WindowAdapter() {
#Override
public void windowClosing(.....
because I thought from there I could publish() something to my SwingWorker to tell it call loseFocus on everything. No such luck; publish() is protected.
Basically I need to do one last operation on my various widgets when X is clicked. How do I?
Edit: I should note that each editable widget (dropdown, JTextPane, etc) has been extended to hold the actual relevant data. All the data for that widget, e.g. whether the value the user typed is valid, what it was before he edited it, etc. is in those extended class instances. There's no other place values are held; this isn't model-view-controller.
The reason for this is that widgets can get changed either by user actions or network messages; a message can come in that throws out an existing widget entirely and replaces it with one with new content. In other words, doInBackground is in a permanent read-loop, reading network update messages and publish()ing those update requests to process(). User action happens as usual, between calls to process().
Bottom line,there's no global data structure to go to at exit time to get values. They're all in dozens to hundreds of data structures managed by the swing worker thread.The app itself, outside that swing worker thread, doesn't even know what sort of values and widgets exist - all widgets are created, placed and destroyed by network messages from the server. The rest of the app (what little there is) couldn't safely get to the data if it wanted to, unless I implemented a whole lot of shared data and locking.
It all works flawlessly, and I'd rather not redesign it all for this one tiny shutdown case. It just never occurred to me that I couldn't publish an extra "shut down" message into the work queue for process() from outside that thread. (I mean thread safe queues are trivial to implement; why didn't they?)
If the answer is "you can't talk to swing at shut down", I'll live with it. I do have a potentially evil workaround - I could have x do nothing but send a message to the server, which could write back a "you should shut down message" which could do the rest. But that seems ungainly.
The short answer is, there isn't a good solution. I tried installing a shutdown hook and publishing a message to the swing thread to tell it to finish up, and then gave the shutdown thread a 500ms sleep to give process() time to happen. process() wasn't called. publish() alone apparently isn't enough, once shutdown starts.
Bottom line, don't put data you need to get at in swing threads. Global data and synchronized functions is the only way to go.

Check if time has passed most efficient t alternative Storing threads on a hashmap or using nanoTime()

I am currently doing a big Java project that involves handling multiple requesta from different users and I would like to know what way is more efficient for handling a wait time. For example: user A cannot press the button in 5 seconds.
First alternative: Have a hashmap where I store the user ID with the thread ID. Then start a thread to run a command in x time. The command is remove A from hashmap.If user A clicks the button it checks if hashmap contains he's ID and then cancellation the event. If I wanted to remove him sooner I have the thread ID stored.
Second alternative: Have a hashmap with user ID and nanoTime + 5sec. If hashmap time value is greater than actual time then button cannot be pressed. Then user ID is removed.
If you can think of any other way efficiency wise it is welcome.
The first way is definitely bad, threads are expensive and there is no good reason to use this approach here.
You could go with the second approach, but don't use nanoTime unless you need to. It seems like System.currentTimeMillis() would be sufficient. Also, if this is a multi-threaded application (sounds like it is), synchronize access methods to your map or, better yet, use a ConcurrentMap. You may want to store the original timestamp, add the wait time when you check -- it's just cleaner design IMO. You can have a single thread periodically cleaning this map.
Finally, if this is a web application, you could simply attach the timestamp to the user session. I think it should be possible with pretty much every servlet container and server platform.

java application multi-threading design and optimization

I designed a java application. A friend suggested using multi-threading, he claims that running my application as several threads will decrease the run time significantly.
In my main class, I carry several operations that are out of our scope to fill global static variables and hash maps to be used across the whole life time of the process. Then I run the core of the application on the entries of an array list.
for(int customerID : customers){
ConsumerPrinter consumerPrinter = new ConsumerPrinter();
consumerPrinter.runPE(docsPath,outputPath,customerID);
System.out.println("Customer with CustomerID:"+customerID+" Done");
}
for each iteration of this loop XMLs of the given customer is fetched from the machine, parsed and calculations are taken on the parsed data. Later, processed results are written in a text file (Fetched and written data can reach up to several Giga bytes at most and 50 MBs on average). More than one iteration can write on the same file.
Should I make this piece of code multi-threaded so each group of customers are taken in an independent thread?
How can I know the most optimal number of threads to run?
What are the best practices to take into consideration when implementing multi-threading?
Should I make this piece of code multi-threaded so each group of customers are taken
in an independent thread?
Yes multi-threading will save your processing time. While iterating on your list you can spawn new thread each iteration and do customer processing in it. But you need to do proper synchronization meaning if two customers processing requires operation on same resource you must synchronize that operation to avoid possible race condition or memory inconsistency issues.
How can I know the most optimal number of threads to run?
You cannot really without actually analyzing the processing time for n customers with different number of threads. It will depend on number of cores your processor has, and what is the actually processing that is taking place for each customer.
What are the best practices to take into consideration when implementing multi-threading?
First and foremost criteria is you must have multiple cores and your OS must support multi-threading. Almost every system does that in present times but is a good criteria to look into. Secondly you must analyze all the possible scenarios that may led to race condition. All the resource that you know will be shared among multiple threads must be thread-safe. Also you must also look out for possible chances of memory inconsistency issues(declare your variable as volatile). Finally there are something that you cannot predict or analyze until you actually run test cases like deadlocks(Need to analyze Thread dump) or memory leaks(Need to analyze Heap dump).
The idea of multi thread is to make some heavy process into another, lets say..., "block of memory".
Any UI updates have to be done on the main/default thread, like print messenges or inflate a view for example. You can ask the app to draw a bitmap, donwload images from the internet or a heavy validation/loop block to run them on a separate thread, imagine that you are creating a second short life app to handle those tasks for you.
Remember, you can ask the app to download/draw a image on another thread, but you have to print this image on the screen on the main thread.
This is common used to load a large bitmap on a separated thread, make math calculations to resize this large image and then, on the main thread, inflate/print/paint/show the smaller version of that image to te user.
In your case, I don't know how heavy runPE() method is, I don't know what it does, you could try to create another thread for him, but the rest should be on the main thread, it is the main process of your UI.
You could optmize your loop by placing the "ConsumerPrinter consumerPrinter = new ConsumerPrinter();" before the "for(...)", since it does not change dinamically, you can remove it inside the loop to avoid the creating of the same object each time the loop restarts : )
While straight java multi-threading can be used (java.util.concurrent) as other answers have discussed, consider also alternate programming approaches to multi-threading, such as the actor model. The actor model still uses threads underneath, but much complexity is handled by the actor framework rather than directly by you the programmer. In addition, there is less (or no) need to reason about synchronizing on shared state between threads because of the way programs using the actor model are created.
See Which Actor model library/framework for Java? for a discussion of popular actor model libraries.

Is there a more ideal way to send draw commands?

I'm still working on moving my android app over to OpenGL and i'm once again having an issue.
I have gotten to the point where everything FUNCTIONS, the only problem is that the animation seems a little juddery.
I'm monitoring the frame rates and seeing that the drawing thread isn't slowing down, but every once in a while, the main loop slows a bit and I suspect I'm having a problem I was worried about.
The way the app works is that as new objects (say for instance, enemies) are created, 2 objects are actually created. The first one is created and mapped in the main thread, and then in it's constructor, it creates a mesh object which is then added to a group to be drawn continuously by the renderer.
Every time an attribute for the object is changed, (such as its coordinates) The object relays the necessary command to its mesh counterpart (in this example to translate the mesh.)
It was suggested that this was thread safe communication, but i'm having my doubts. I also notice a greater amount of frame skip when new objects are created, I can fix this somewhat by reusing the same mesh object for identical Game objects, but I don't believe this will fix everything by itself.
Can you think of a way to make this more efficient and thread-safe?
Another possible solution: The game logic does not HAVE to go at full speed (realtime) I have it actually set up so that no updates are made untill 33 millis pass. So obviously, I should have plenty of time between frames to draw, can I set it up so that draw is only called on command in the thread (after the game logic has been updated)?
It looks like you need something like a ScheduledThreadPoolExecutor.
With one of these you could put your renderer on a schedule so it executes at 30fps leaving your main/control thread to do whatever it needs to do to the object map between frames.
I don't think you need any wait/notify interlocking as all you really need is to block access to the map while the renderer is walking it. To do this you just need to make the map synchronized. As this will only happen once every 1/30th of a second you are certainly not introducing a significant overhead.
Your main aim should be to put as little unnecessary load on the CPU as possible, this is the key to smooth multithread work. Try to spend as much time as possible either sleeping or blocked.
Added
I subtract the time it took to loop from 33ms, and use the result to specify the length of sleep().
I wonder if that may be part of your issue. On a Windows machine you often get a 15ms resolution on the currentTimeMillis so your sleeps may end up hardly sleeping at all. It may be worth experimenting with a ScheduledThreadPoolExecutor just to see if it improves your timing. ... oops ... this is Android isn't it. Still ... it may be worth a try.

Need an elegant way to invoke arbitrary code on a specified interval

Ok, I have a game server running in Java/Hibernate/Spring/Quartz. The game clock ticks with a Quartz timer, and that works just fine.
However, I have many other things that need to happen at specific, tweakable intervals (in game time, not real time).
For instance, every 24 hours game time (~ 47 minutes real time, depending on the servers clock multiplier) a bunch of different once-a-day game actions happen, like resupply, or what have you.
Now, the current system is pretty rough, but works - I have a table in the database that's essentially a cron - a string key, the execution time of the next event and then hours, minutes, seconds and days until the next one after that. The time ticker checks that and then fires off a message with that code (the events string key) in it to a queue, adding the days, minutes, seconds to the current time and setting that as the next execution time.
The message listener is the grody part - it switches on the key and hits one of its methods.
Now I understand that this can work just fine, but it really doesn't sit well with me. What would your solution be to this, to have each piece of code in its own little class? What design pattern covers this? (I'm sure there is one). I have a few ideas, but I'd like to hear some opinions.
Rather than a switching on a set of codes, you could use the code as a key into a map, where the values are objects that implement a handler interface. This allows you to be much more flexible in adding new event types.
The pattern looks something like this:
private final Map<String, Handler> handlers = new TreeMap<String, Handler>();
public void register(String event, Handler handler) {
handlers.put(event, handler);
}
public void handle(String event) {
Handler handler = handler.get(event);
if (handler == null) {
/* Log or throw an exception for unknown event type. */
}
else {
handler.execute();
}
}
Rather than explicitly registering handlers, you could use something like Java 6's ServiceLoader to add new behaviors just by dropping JARs into the class path.
I would use a variant of the Command Pattern. I would extend the Command pattern to make a IIntervalCommand class. It would have a interval property, and a readonly CanExecute property in addition to the Execute method.
Then you create a CommandList Class that holds a list of IIntervalCommands. It would have a method called CheckToExecute that you pass it the current game time. The CheckToExecute method would traverse the list calling CanExecute for each command. CanExecute will return true if the elapsed time has occurred. If CanExecute return true then CheckToExecute will call the Execute Method of the object implementing IIntervalCommand.
Then adding additional game events is a matter of creating a new class implementing IIntervalClass. Instantiating the Object and adding it to the IntervalCommandList.
If the processing of the event is time consuming then the command could spawn the processing as a separate thread. It will return false to it's CanExecute property until the thread returns even if the interval has passed again. Or you have it spawn off another thread if the interval passed again.
You avoid the giant case statement. You could eliminate the database and setup the parameters when you instantiate the objects. Or keep it and use it as part of a factory that creates all your IIntervalCommands.
Instead of switching on the key you can use a hashtable to dispatch these events. This way your timer events don't need to know about each other.
It should be possible do have something like:
timerQueue.registerHandler("key",new TimerHandler(){
// do something timer related
});
This way you can restart java code handling events without losing your persisted queue of events.
http://en.wikipedia.org/wiki/Priority_queue'>Priority queues are worth looking at if you have not already.
I personally wouldn't put this in the database but rather keep a separate service running in the background. Then my webservice or web application would communicate with this service through interprocess communication. Don't know how this translates into java world though.
Conceptually I think you're doing two things;
Firstly you have a scaled version of time. As long as the relationship between this time and wall-clock time remains constant I'm fairly sure I'd just delegate this scaling behavior to a single class, that would have signatures like
DateTime getFutureTime( VirtualTimeSpan timespan)
I'd be using this to map virtual time spans to instances of real-time. Thereafter you can operate in real-time, which probably simplifies things a little since you can the use standard scheduling features.
The second part regards scheduling work for a future worker process. There's a number of core technologies working with this; Conceptually I think JMS is the java-grand-dad of a lot of these, it defines concepts much like the ones you're using and what you need. I think taking a look at JMS is fine for seeing concepts you may find interesting, it uses selectors to send tasks to specific workers, much like the ones you decribe.
Alas, JMS never seemed to fit the bill for most people. A lot of people found it was too heavyweight or the implementations too buggy. So usually people ended up with home made queue technologies. But the concepts are all there. Can't you just use quartz ?

Categories

Resources