Interrupting java stream gracefully

I wrote a java puzzle game. I wrote the code this way: there is a thread that starts when the application starts, and as soon as the game goes on, there is a second thread that just works in an infinite loop - the main game loop. The second thread looked like this:

public void run() { init(); while (shouldIRun) { updateGameState(); checkUserInput(); updateGameScreen(getGraphics()); this.flushGraphics(); } } 

Beautiful. This thread just starts and starts until I want to kill it, when I just set the boolean shouldIRun to false, after which it exits gracefully.

But later I realized that I want more. The game is a puzzle game, and the player can take the wrong action and then get stuck. When this happens, they can run the form and select the "restart" option. Then the restartLevel flag restartLevel set, and when the infinite loop gets into the updateGameState() method, the level is restarted. But for me it looks like a game - I don’t want to start changing the variables of the objects that are used in the main loop in case of concurrency problems, although I'm probably paranoid. In practice, what I understood, what I wanted to do, was very clear: I just wanted to pause the flow of an infinite loop, change the variables to what I wanted, and then restart.

I did it as follows:

 public void run() { init(); while (shouldIRun) { if (shouldIWait) { iAmWaiting=true; while (shouldIWait) { }; iAmWaiting=false; } updateGameState(); checkUserInput(); updateGameScreen(getGraphics()); this.flushGraphics(); } } 

I think the following. If now I want to “pause” this second stream, from the “base” stream, I simply set the shouldIWait variable to true, and then simply loop until we notice that the iAmWaiting variable iAmWaiting also true. Now I know for sure that the second thread is suspended, and I know exactly where it stopped, where it “suspended”, I actually mean “stuck in an infinite loop for a while”. Now I can encounter some important variables, restart the level and generally figure things out, and then finally set shouldIWait back to false and turn it off, we go again.

My question is, this works fine for me, but can be frustrating. Is there some completely standard way to do what seems to be commonplace to pause a thread at a given point and then restart it when I'm ready, which is better than what I'm doing? In particular, I suspect that “installing java in an infinite loop” may not be a smart task.

+4
source share
2 answers

This is usually what you would use Object.wait() and Object.notify() for.

There are several ways to implement it for your situation, but here is a simple example:

 Object monitor = new Object(); volatile boolean done = false, wait = false; /* Running on one thread: */ public void run() { synchronized(monitor) { while(!done) { while(wait) { monitor.wait(); } gameLogicAndStuff(); } } } /* Running on another thread: */ public void showResetForm() { wait = true; synchronized(monitor) { actuallyShowResetForm(); wait = false; monitor.notifyAll(); } } 
+1
source

It may be easier to just kill the stream and start a new one from a new level.

If there is information that needs to be transferred from one level to another, perhaps you could reorganize your code to collect some general information first and then start the flow for each level. (And by starting the thread, I mean using the thread pool.)

I do not think that what you are doing now with lively expectation is evil. As Ben Flynn mentioned in the comments, you can make this busy while waiting by going through Thread.sleep (50).

+1
source

Source: https://habr.com/ru/post/1394709/


All Articles