This question already has an answer here:
Loop doesn't see value changed by other thread without a print statement
(1 answer)
Closed 7 years ago.
So, the other day I made a fractal drawing program, and when it got too slow, I thought I would make it a bit faster by multithreading it. So I introduced a couple of threads to each draw a portion of the image. To know when I was done with the threads, I introduced two variables, AMOUNT_OF_THREADS and threadsDone. I created AMOUNT_OF_THREADS threads, that each drew their own partition and increased threadsDone when done. In the main method, I put in
while (threadsDone < AMOUNT_OF_THREADS)
;
It surprised me that that loop never finished looping. I knew it because each thread printed out "Thread done" and when the main method loop was done it should have printed out "Main done" but it didn't. I tried to print out threadsDone < AMOUNT_OF_THREADS and now the loop stopped. Weird.
I did some further testing and this problem seems only to occur if the thread takes >2ms to run or the loop takes >2ms each time it loops. Sometimes this bug occurs when the thread takes 2ms to run.
I suspect that the print function made the loop take >2ms to run and that made it work when I printed out the value, but I still wonder why this happens.
So my question is, why does this happen? Is it a bug in the compiler/JVM, or anything else? I asked my dad, and he replied after thinking for a few minutes that it has to be the while loop running too fast, but he wasn't sure.
Here's a little example of some code that has this problem:
public class WhileThread {
public static boolean threadDone = false;
public static void main(String[] args) {
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
threadDone = true;
System.out.println("Thread done.");
}
}).start();
while (!threadDone) {
}
System.out.println("Main program done.");
}
}
When you change the 0 in the Thread.sleep into a 10, this bug never happens.
If it matters, I use a Macbook Air with Java SE 8.
So my question is, why does this happen? Is it a bug in the compiler/JVM, or anything else?
It's not a bug, it's a deliberate design decision. To make code like this work reliably, JVMs would have to assume that any thread could change any variable at any time unless they could prove that this couldn't happen. This would inhibit all kinds of extremely valuable optimizations and make Java code run much more slowly.
So instead, these optimizations were explicitly allowed and several methods (volatile, synchronized, and so on) were added to allow coders to show where variables could have their values changed by other threads.
Related
I want to write a bot for a online game using the Robot class. My problem is now, that the method Thread.sleep() or robot.delay() is to inaccurate. Outside the game they work perfectly fine, with a deviation of approximately only 2 - 3 ms. But when the game is in focus, the methods have a deviation of +5 - +20 ms or even more. That is sadly enaugh to make my bot unusable. Is there any way to make these methods more accurate? Or are there any other ways to solve this problem?
There is no difference
If you browse the source for the JDK, Robot.delay() ends up calling Thread.sleep().
public void delay(int ms) {
checkDelayArgument(ms);
Thread thread = Thread.currentThread();
if (!thread.isInterrupted()) {
try {
Thread.sleep(ms);
} catch (final InterruptedException ignored) {
thread.interrupt(); // Preserve interrupt status
}
}
}
You might be able to give the Java process a higher priority then the game, tasks might be executed more quickly after being given to the scheduler.
This question already has answers here:
What is the difference between a static method and a non-static method?
(13 answers)
Closed 4 years ago.
So I'm learning java and I kinda got confused here...
So while learning threads I learned that it is necessary to extend Thread class or implement Runnable class.
And while going through this program Thread.sleep() is used without doing any of the above process.
link:
http://www.abihitechsolutions.com/applets-mini-project-in-java-free-source-code/
Can someone explain me what is going on?
By using Thread.sleep(X) actually you are pausing execution for time X.
This is suitable for sending requests to servers or database. Nobody wants to send a huge request to DB or server in one time.
Making small portions is always reasonable. You can divide your requests and send them by waiting specified time duration.
This is one of the important usages of Thread.sleep()
There is a much proper way to handle thread pausing which is wait/notify. I suggest using it.
You can check from there;
https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
It is much better to implement Runnable than to extends Thread. Thread.sleep() is a static method so you can call it from anywhere.
class RunMe implements Runnable {
#Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("Hello");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Bear in mind that all Java code runs in a thread so calling Thread.sleep() can be done anywhere.
The reason why you can use Thread.sleep without actually creating a thread is because the main program is also running on a thread. You're simply calling sleep on the main thread. When you call Thread.sleep, java will figure out for you which thread it is actually running on.
This question already has an answer here:
Loop doesn't see value changed by other thread without a print statement
(1 answer)
Closed 7 years ago.
I have experienced weird behaviour while coding a simple game. Basically, I create a thread with an infinite loop that fires an event in my game every couple of seconds. With the Sysout(runAnimation) in place everything works fine. However as soon as I remove it the even stops occurring.
It appears that the system.out calll is affecting the behavior of the program, does anyone have an idea why this could be happening
Here is the loop:
private void run(){
long lastTime = -1;
while(true){
int timePerStep = (int) Math.ceil(ANIM_TIME/frequency);
System.out.println(runAnimation);
if(runAnimation && System.currentTimeMillis() - lastTime > timePerStep){
lastTime = System.currentTimeMillis();
controller.step();
try {
Thread.sleep(timePerStep);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
It's started during the construction of my class as follows:
animThread = new Thread(new Runnable() {
#Override
public void run() {
GUIView.this.run();
}
});
animThread.start();
The System.out.println() call is synchronized (most PrintWriter method calls are) so I suspect that there is something that you are not synchronizing on inside of your code. I wonder about the runAnimation field. Could it be that it is set in another thread? Maybe it needs to be volatile? Any field that is modified in one thread and read in another needs to be synchronized or volatile. Reading the Java thread tutorial around synchronization may help.
Without seeing more of the code, it's hard to put a finger on it but I suspect this answer will help anyway.
Lastly, do you really want your thread to spin until runAnimation is true? That's a very bad practice. Maybe you should sleep for some time in the loop if runAnimation is false as well. Another idea is to use a CountDownLatch or other signaling mechanism to pause your thread until it needs to do the animation.
If your field is not volatile, the JIT can assume it doesn't change and place it in a register or even inline it in code. Placing a system call in this tight loop can
prevent the JIT from optimising the code this way as it cannot make assumptions about whether the thread modifies the field.
slow down the loop so it is not run 10,000 times (which is the point at which the JIT kicks in)
For more details, here is an article I wrote on the subject Java Memory Model and optimisation.
I'm trying to learn some basic java programming for games.
I'm following this tutorial here.
Their skeleton code for the run method in an applet:
public void run ()
{
// lower ThreadPriority
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
// run a long while (true) this means in our case "always"
while (true)
{
// repaint the applet
repaint();
try
{
// Stop thread for 20 milliseconds
Thread.sleep (20);
}
catch (InterruptedException ex)
{
// do nothing
}
// set ThreadPriority to maximum value
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
}
}
In this code they initially set the thread priority to minimum. Then inside the loop they set it to maximum.
I was wondering what the purpose of this is?
I don't know why they decided to set the priority to minimum initially. I think this is pointless.
However, setting the priority to higher than normal (maybe maximum is an exaggeration) does make sense.
In general, if you have a thread that repeatedly performs a short action then sleeps, what you generally want is to try and maximise the probability of the thread "kicking in on time, doing its thing, then going back to sleep" on each iteration. Broadly speaking, setting the thread priority to higher than average increases the chance of this happening. This is particularly true on Windows, where thread priority essentially affects what thread gets scheduled in at the points where the thread scheduler is deciding "what to run next".
You might want to read through an article I wrote a couple of years ago on Java thread priority that may help to explain some of the issues involved.
Every 3 seconds, I want the server to send a message.
To do this, I have this code.
try {
Thread.sleep(3500);
getPackets().sendGameMessage("[Server Message]: Remember to vote!");
} catch (InterruptedException e) {
e.printStackTrace();
}
The code works of course, waits 3 and a half seconds, sends the message.
But how can I make it loop, so every 3 and a half seconds, it will send it without stopping?
I'm a bit surprised that someone tackling networking in Java doesn't know how to put code in an infinite loop. Thus, I wonder if your real question is "is there a better way?"
To that question, I would say that you should consider using either java.util.Timer to send the message, or using scheduleAtFixedRate() from a ScheduledExecutorService obtained from Executors.newScheduledThreadPool().
The best way is to use a Timer. See Java how to write a timer
spawn the above code in a separate thread and enclose it within a while(true) loop.
This kind of code is not very useful because it blocks the current thread and also seems to unnecessarily clutter the program logic. It's better to delegate it to a worker thread that executes the send in the background. Also Thread.sleep is known to be inaccurate.
As of the latest Java versions, I think the most elegant way to do it is using ScheduledThreadPoolExecutor:
ScheduledThreadPoolExecutor executor = new ScheduledThraedPoolExecutor(1);
executor.scheduleWithFixedDelay(new Runnable() {
public void run() {
getPackets().sendGameMessage("[Server Message]: Remember to vote!");
}
}, 0, 3500, TimeUnit.MILLISECONDS);
Also you don't have to worry about that annoying InterruptedException.