Java code needs a system.out.println statement to

2019-03-07 07:48发布

问题:

This question already has an answer here:

  • Loop doesn't see value changed by other thread without a print statement 1 answer

I wanted to know if anyone else experienced this problem. This one portion of code in my game relies on a system.out.println statement to work. without it, it won't function properly

while(isladder){
 t = Map.tiles[(int) (Player.x + 15 + ScrollManager.xoffset) / 32][(int) ((Player.y ) + ScrollManager.yoffset) / 32];
 if(t.row == 3 && t.col == 5){
        ScrollManager.dy = -.5;
        System.out.println(t.row);
 }else{
    ScrollManager.nogravity = false;
 }
}

This is in a thread that starts when someone hits the up key. It is a ladder for a 2d minecraft game I'm making. without the system.out.println code, the player will keep floating up in the air. with it, the player will stop at the top of the ladder like normal

(update) I fixed this just by adding a Thread.sleep(1) so that it runs smoother

回答1:

You're being hit by in-Thread memory caching, an optimization technique that the JIT uses to speed up your program when it determines that a given block of memory has no synchronization concerns, and does not need to be synced up with main memory.

Related question: How to demonstrate java multithreading visibility problems?

What is essentially happening is this:

1) JIT loads the class, and reads in the while() loop 2) The isladder variable is not declared volatile, and is not retrieved through any synchronized means, so the JIT thinks:
"Oh, this variable is basically local - I'ma have the Thread cache the value of isladder locally, and just use that, so it runs faster."

When you don't include any operations in the loop that tend to trigger context-switching, like Thread.sleep(), System.out.println() I/O, the cached value for isladder never gets refreshed.

While a Thread.sleep() solves the problem at the surface, it does not address the root problem in your code, which is the lack of synchronized access to game state. This thread you have posted only seems to modify the scroll window, and so is fairly innocuous, but when you have Threads controlling things like animated objects, enemies, etc., poor multithreading practices lead to spontaneous, seemingly random, unpredictable results.