Why not use a scheduledExcecutor for a game loop - java

I'm currently reading about game development, every time I see a game loop implemented it is always the same way.
A while(true) block, with a sleep inside for the FPS.
And I'm asking myself, why shouldn't I use a scheduledExcecutor, it seems like the obvious choice?
I mean, I'm sure I'm wrong here, it's unlikely that I'm the first one to think of this, but WHY not ?

First of all, look at some of the evolution of the traditional game loop. Your while(true) + sleep example is the simplest one.
Then people noticed that games were affected by the speed of the computer they were running on. Look up "variable time step game loop" on Google, for examples of how this is dealt with.
Now read over the docs on the ScheduledExecutorService. Neither scheduleAtFixedRate nor scheduleWithFixedDelay are quite what you'd want for a game.
Also, scrolling down in the docs, you'll notice "If any execution of the task encounters an exception, subsequent executions are suppressed." This can cause your game loop to abruptly terminate if you don't handle every possible exception.
There's nothing to stop you from extending the ScheduledExecutorService and modifying it to suit your needs, but I wouldn't recommend it as-is.

The main reason is probably simply that most of the code you are reading was coded before (or following patterns that were coded before) the concurrent package came out/was in heavy use.
A secondary might be trust. When you are coding something that critical to your app you want to be sure exactly how it behaves. The while(true) loop makes it very clear exactly what's going on... You'd have to spend some time dealing with the various executors before you became truly comfortable with one.
There should be a solution that solves your problem, I'm sure you can find something that fires regularly, and has an adjustment in case one iteration takes a little longer than expected.
You may even want to build your own executor. The pattern itself is fine, it's just finding a way to make it work for you.

Related

NullPointerException whilst learning concurrency in Scala

I'm having a little problem at the moment. My latest assignment is to create a rock paper scissors program which will run concurrently and output various values. Sounds simple and trivial, I know, but a little fun and I have been allowed to use scala which I had no knowledge of so thought it would be interesting.
Now the error is confusing me. I am receiving a NullPointerException on Thread 10, and have spent an awful long time trying to find it to no success. I have 6 classes so it would be impractical of me to put all of the code in, but I will put a few snippets.
result = Shapes.Winner(player1.getChoice(), player2.getChoice())
This is the line giving the error. Player1 and Player2 are simply objects from a class I have made, and they have been dequeued in.
Now for the confusing part. If I add a simple line in another class:
println(wait.getChoice())
it all works. This line has no relation to the first line above, and was simply for testing. But now when I take it out, I get the error. I would just leave it, but as you can see, it prints a load of rubbish onto the terminal.
I really have no idea what I'm doing wrong, and would love some help.
Feel free to ask for more snippets of the code, and thank you in advance for any help.
The problem is that you use synchronized incorrectly. You should wrap all calls to Referee.queue into Referee.synchronized {} blocks in order to synchronization to work. Otherwise the calls are not synchronized, and it's possible for one thread to modify Referee.queue without other thread notice.
Otherwise you should use thread safe collection. For example when I substitute scala.collection.mutable.Queue with scala.collection.mutable.SynchronizedQueue in the Referee class everything works ok, and you don't need to synchronize access to queue.
Even better use java.util.concurrent.ConcurrentLinkedQueue instead, because
SynchronizedQueue is deprecated in scala_2.11

Java Event Generation

I want to design a system which will generate a specific event at a constant rate and this will continue doing in the background. In the foreground it give output of some other events if I want.
But the background event will not stop. What is the best way to achieve it in java?
This is the definition of Threading and it needs to come with some level of understanding.
On a simplest level, make a Thread that sleeps for an amount of time then executes your code. There are lots of other ways to do it, but few are shorter than just overriding the run method of a thread.
If you want something more abstract, look through the concurrent package in the Java docs, there are many methods that do exactly what you want, and java.util.timer is a good one to look at as well.
Be aware of variables and collections that might be accessed by different threads at the same time. Also be aware if you have a GUI that you shuold not update your GUI from this new thread.
Edit to add a Non-thread solution
(I don't think this is really what you want, but in the comments you asked for a non-threaded solution).
If you wish to do this without threads (meaning you really wish to do it in your current thread) you have to occasionally "Interrupt" your current thread to check to see if your other task needs to process. First you need a method like this:
long lastRun=System.currentTimeInMillis();
final long howOftenToRun=60*1000 // every minute
testForBackgroundTask() {
if(lastRun + howOftenToRun < System.currentTimeInMillis()) {
// This will drift, if you don't want drift use lastRun+=howOftenToRun
lastRun=System.currentTimeInMillis()
// this is where your occasional task is.
// The task could be in-line here but of course that would violate the SRP
runBackgroundTask()
}
}
After that, you need to sprinkle testForBackgroundTask throughout your code:
lotsOfStuff....
testForBackgroundTask()
longMethod()
testForBackgroundTask()
morestuff...
testForBackgroundTask()
...
Note that if longMethod() takes a really long time then you will need to put calls to testForBackgroundTask() inside it as well.
I know this is ugly, and the uglyness of this solution is why threads are used. The only advantage is that it will absolutely prevent threading conflicts.
The other single threaded solution--making your code event driven--is even harder and seriously impacts your code (There is a construct called a Finite State Engine made for this purpose).

Java concurrency - marbles moving around a circle

Let's imagine a simple Java program, where there are 5 2D marbles moving around in a circle in a fixed order. You can control the speed of every marble keeping in mind that slower marble is blocking the marble moving faster (they can't overtake). They all move in one direction in a circle. What would be the best way to program this? The idea is to assign a separate thread to every marble, that's actually one of the requirements.
Then I create five threads, synchronize the "move" method on some object common to all threads. The next step is checking whether I can move the marble forward, if there is some free space. So before I move, I check if there is free space and then take action. Is it necessary or at least a good idea to use wait() and notify() mechanism here?
Thanks for help.
Well, I'm not going to code your homework for you, but here is a high level look at it.
You will need each marble to update it's position at regular intervals, so some type of looping is required. This loop is commonly known as a game loop. Here is a discussion of various types of them, going from simple to complex. http://www.java-gaming.org/index.php?topic=24220.0 For your project, something simply may be sufficient, but I don't know the requirements of it.
Each time a marble tries to move, it must check to make sure it isn't being blocked. If you have the move method synchronized, as you mentioned, then only one marble should be able to move at a time, so that should avoid concurrency issues.
Except for using a Thread.sleep in your game loops, I don't see any reason for you to doing any waiting. Java has a synchronize keyword, which can be used to lock the shared object that you mentioned using for movement, to avoid the concurrency issues. So I don't believe wait and notify are necessary.
Just my thoughts, I hope it is of some help.

Explain the timing causing HashMap.put() to execute an infinite loop

As a number of people have noted and encountered HashMap.put can go into an infinite execution loop when used concurrently (see GRIZZLY-1207, JGRP-525, possibly HHH-6414, and this SO answer).
HashMap is clearly documented as not thread safe. Obviously, the correct fix is to use a thread-safe implementation of Map, ConncurrentHashMap in particular. I'm more curious about the concurrent timing that causes the infinite loop. I encountered this loop recently with a Java 7 JRE and would like to understand the exact causes. For example, is this caused by multiple puts at the same time?
A look inside HashMap.put shows that HashMap.Entry contains a link to the next node (in the bucket?). I assume these links are getting corrupting to contain circular references, which is causing the infinite loop. However, I still don't understand exactly how that corruption is occurring.
To the contrary of what many people think, the main issue with multi-threading and HashMaps is not just a duplicate entry or a vanishing one... As you said, an infinite loop might occur when two or multiple Threads concurrently decide to resize the HashMap.
If the size of the HashMap passes a given threshold, several threads might end up trying to resize it at the same time, and if we are lucky enough (you deployed the code in production already) they will keep going forever...
The issue is caused by the way the void resize(int newCapacity); and void transfer(Entry[] newTable); are implemented, you can take a look at the openjdk source code yourself. A mix of bad luck, good timing, entries that get reversed (ordering is not required in this data structure) and that end up to mistakenly referring to each other while a thread keep going while(e != null)...
While I could try to give you an explanation myself, I want to give credit to Paul Tyma's post (I cannot do better than him anyway) where I learned how this worked the first time I decided to figure out why I wasn't hired for a job several months ago...
http://mailinator.blogspot.com/2009/06/beautiful-race-condition.html
As Paul says, the best word to describe this race is condition is: beautiful

Weird Java problem, while loop termination

I have a piece of code that looks like this:
Algorithm a = null;
while(a == null)
{
a = grid.getAlgorithm();
}
getAlgorithm() in my Grid class returns some subtype of Algorithm depending on what the user chooses from some options.
My problem is that even after an algorithm is selected, the loop never terminates. However, that's not the tricky bit, if I simply place a System.out.println("Got here"); after my call to getAlgorithm(), the program runs perfectly fine and the loop terminates as intended.
My question is: why does adding that magic print statement suddenly make the loop terminate?
Moreover, this issue first came up when I started using my new laptop, I doubt that's related, but I figured it would be worth mentioning.
Edit: The program in question is NOT multithreaded. The code for getAlgorithm() is:
public Algorithm getAlgorithm ()
{
return algorithm;
}
Where algorithm is initially null, but will change value upon some user input.
I believe the issue has to deal with how grid.getAlgorithm is executed. If there is very little cost associated with executing the method, then your while loop will cycle very quickly as long the method continues to return null. That is often referred to as a busy wait.
Now it sounds like your new laptop is encountering a starvation issue which didn't manifest on your old computer. It is hard to say why but if you look at the link I included above, the Wikipedia article does indicate that busy waits do have unpredictable behavior. Maybe your old computer handles user IO better than your new laptop. Regardless, on your new laptop, that loop is taking resources away from whatever is handling your user IO hence it is starving the process that is responsible for breaking the loop.
You are doing active polling. This is a bad practice. You should at least let the polling thread sleep (with Thread.sleep). Since println does some io, it probably does just that. If your app is not multithreaded it is unlikely to work at all.
If this loop is to wait for user input in a GUI then ouch. Bad, bad idea and even with Thread.sleep() added I'd never recommend it. Instead, you most likely want to register an event listener on the component in question, and only have the validation code fire off when the contents change.
It's more than likely you're program is locking up because you've reached some form of deadlock more than anything else, especially if your application is multithreaded. Rather than try to solve this issue and hack your way round it, I'd seriously consider redesigning how this part of the application works.
You should check getAlgorithm(), there must be something wrong in the method.
There are two scenarios:
Your code is really not meant to be multi-threaded. In this case you need to insert some sort of user input in the loop. Otherwise you might as well leave it as Algorithm a = grid.getAlgorithm(); and prevent the infinite loop.
Your code is multi-threaded in which case you have some sort of 'visibility' problem. Go to Atomicity, Visibility and Ordering or read Java Concurrency in Practice to learn more about visibility. Essentially it means that without some sort of synchronization between threads, the thread you are looping in may never find out that the value has changed due to optimizations the JVM may perform.
You did not mention any context around how this code is run. If it is a console based application and you started from a 'main' function, you would know if there was multi-threading. I am assuming this is not the case since you say there is no multithreading. Another option would be that this is a swing application in which case you should read Multithreaded Swing Applications. It might be a web application in which case a similar case to swing might apply.
In any case you could always debug the application to see which thread is writing to the 'algorithm' variable, then see which thread is reading from it.
I hope this is helpful. In any case, you may find more help if you give a little more context in your question. Especially for a question with such an intriguing title as 'Weird Java problem, while loop termination'.

Categories