Java asynchronously wait x seconds - java

To give some details about what I'm trying to do: I'm making a Minecraft plugin in Java. I have an Object which is bound to the Player object of Minecraft using a HashMap.
I have a method in this object which is something like:
public void faint() {
... //Apply the effect on the player
//wait for x seconds, and if the player didn't already wake up, wake them up. (player.wakeUp())
}
Obviously, there will be a lot of stuff going on, so I want this to happen asynchronously. The timer will go on in the background and it won't block anything else in the code.
Sorry if my question is too simple, but I really checked the web and I'm new to Java, so forgive my ignorance.

You can create a separate thread by implementing a Runnable interface like this and do the delay in there.
// This is happening in the main thread
Thread thread = new Thread(){
public void run(){
// This code will run async after you execute
// thead.start() below
Thread.sleep(1000)
System.out.println("Time to wake up");
}
}
thread.start();

Use the Bukkit scheduler.
Bukkit.getScheduler().runTaskLater(yourPluginInstance, () -> {
// put code here to run after the delay
}, delayInTicks);
When the code runs after the delay it will run on the main server thread.

Related

Pausing in Java

So I'm a beginning programmer and I'm trying to make a pong game(but horizontal). There is only one slight problem. After the user has scored a point the ball will immediatly return to the player. I would like to know if there's a way to start a little delay to give the player some time to react. Here is the 'scoring' system I'm using.
Thank you in advance!
if(yBall<=100-barHeight*0.5){
yBall = 300;
xBall = 400;
text_player2 = text_player2+1;
yBallSpeed = yBallSpeed *-1;
xBar = width*0.5 - barWidth*0.5;
//pause for few seconds
}
You can use Thread.sleep(millisecs), see https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#sleep%28long%29
Note, that you "have to put" Thread.sleep(millisecs) in a try-catch block (or add throw to the method):
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {}
In Java you can make the currently executing Thread go to sleep for x milliseconds using
Thread.sleep(1000);
If this is a beginner programming excercise then this might do for you. Make sure you catch the exception that this method throws.
Also please think about if you really want to sleep the thread the game runs on. Maybe you want to keep processing user input (e.g. if he wants to quit) but schedule the new ball bit later. For that, you can check out what Timer is for
It appears that you're doing this in a per-frame operation of your game, so Thread.sleep would be bad practice. Instead of pausing the game, it will make the game hang unresponsively for a certain time period (this may or may not be ok for yours).
Consider using System.currentTimeMillis() instead, which returns the current time in milliseconds:
long deadLine = 0L;
// Your method for updating the game's state
void updateState() {
if (deadline > System.currentTimeMillis()) {
// The game is currently paused. Draw a "Get Ready" string maybe?
return;
}
if (gameShouldRestart()) {
// The game should not do anything for the next two seconds:
deadLine = System.currentTimeMillis() + 2000L;
// Reset game state here.
}
}
Now the updateState() method will return immediately and let the game keep rendering but without doing anything, instead of just lagging the game for several seconds.
You should use a ScheduledExecutorService to invoke an action after a delay without causing the current thread to block. Try to reuse the same ScheduledExecutorService across your whole application, and make sure you shut it down at the end.
final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
try {
executor.schedule(() -> SwingUtilities.invokeLater(() -> {
readyToRestart(); // your method that restarts the action
}), 1, TimeUnit.SECONDS);
} finally { executor.shutdown(); }
Since the ScheduledExecutorService will run the scheduled action on its own thread, you will need to make sure the action does not cause any threading related problems. How you do this depends on what GUI toolkit you are using. In the example I show how to do it in Swing using the SwingUtilities.invokeLater method.

Java Wake Sleeping Thread

I did some reading of other post but didn't find an exact answer to what I'm looking for, so I hope someone can give some some clarification.
I have a program that will run for some time. I have some threads that run in the back ground that perform various tasks, to keep things simple let think of 3 threads. ThreadA performs a task every 10 seconds, where ThreadB does something every 30 seconds and ThreadC does something every 5 mintues.
I don't use busy waiting, and put the threads to sleep for the designated times.
My question is regarding a clean shut down. I have a variable that each of the threads have read access too, so they can see when the user initiates the exit of the program. The next time the threads are active, they exit their loops and join and all is good. But you can see that ThreadC only wakes up every 5 minutes.
The question I have is can I signal the sleeping threads to wake up and exit before their sleep time is over? If this is not possible, do I need to rework the code to use wait() and notify() or is there a better way?
Thread.sleep throws InterruptedException if the thread is interrupted during the sleep. Catch that, and check your flag.
If the threads are sleeping with Thread.sleep(...), you can wake them up with Thread.interrupt(). Make sure you're handling the InterruptedException and testing Thread.currentThread().isInterrupted() in your loops.
You can call the interrupt() method on your thread and will make your Thread go to running state from block state, but it will throw an exception which is InterruptedException which by then you can shutdown your thread in the catch block
Also other solution is that you can use the Timer Task that will call the run method on a certain time you specified without putting your Thread to the block state
example:
public class TimerBomb {
Toolkit toolkit;
Timer timer;
int count = 0;
public TimerBomb(int seconds) {
toolkit = Toolkit.getDefaultToolkit();
timer = new Timer();
timer.schedule(new RemindTask(), seconds * 1000, seconds*1000);
}
class RemindTask extends TimerTask {
public void run() {
//do stuff here
}
}
public static void main(String args[]) {
System.out.println("About to schedule task.");
Thread t = new Thread(new Runnable() {
#Override
public void run() {
new TimerBomb(5);
}
});
t.start();
System.out.println("Task scheduled.");
}
}
It will run every 5 second forever.
You should look into ExecutorService and its shutdownNow() method (which generally interrupts all the active threads). You sense reinventing the scheduling wheel.
All of the other answers are good answers to the question that you actually asked, but none of them gives the best answer to the question that you should have asked. The question is, what's the best way to schedule several periodic tasks that must recur with different periods? The answer is, use a java.util.concurrent.ScheduledExecutorService.
Like all ExeuctorServices, it provides methods, shutdown() and shutdownNow(), for when you want the tasks to stop.

Restarting a thread after it has been left

I have thread which contains a loop
while(isRunning){
}
isRunning is a Boolean variable with the value true, when some clicks on a button it gets false and so it leaves the loop and the run() function of the thread.
I want to create another button that on click it will reenter the run() function.
I am not sure if when I leave the run() function the thread dies or just stops.
I have tried using thread.run() but it didnt work.
Also I have looked for an answer in other's people questins about this matter but nothing seemed to help me. Thanks for the help
When a thread is finish processing it's code, There's no way of restarting it. You can either:
Create a new thread and pass the Runnable to that thread.
If you need to use that run() method often, use an Executor. You can use Executors.newSingleThreadExecutor(), which will supply you with a worker thread. (Reusable thread).
class Example {
static ExecutorService executor = Executors.newSingleThreadExecutor();
static Runnable run = new Runnable() {
public void run() {
}
};
public static void main(String[] args) {
//anytime you wanna run that code..
executor.execute(run);
}
}
If your thread runs to its end, it stops.
It will remain there for you to collect its return status until the thread is cleaned up.
To restart within the same thread, you need an extra control flow.
For instance:
while (restarted) {
while (isRunning) {
}
// Wait for a restart or end click
}
That is what so called worker threads in a thread pool do, which are intended for maximum performance.
But logically, you will probably simply want to create a new thread object and start that one.
new Thread(p).start();
Please read through java concurrency tutorial.
http://docs.oracle.com/javase/tutorial/essential/concurrency/
Just Maybe, guarded blocks might be useful for your case but your case is a little vague to recommend anything specific.
http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html

Thread reusal in Android

I have a code in Android, which is resource intensive. It processes a bitmap and then saves it to the sdcard.
Since running it on the main thread took a lot of time, I did it like this:
new Thread(new Runnable() {
public void run() {
//do work
}
}).start();
But, I found that if I invoked this piece of code before the thread had fully executed, the previous thread just got deleted and overwritten with the new task. The sdcard showed only the last image.
So I wrote a static thread as :
Thread t=new Thread(new Runnable() {
public void run() {
//do work
}
};
But, t.start() cannot be called multiple times. (llegalThreadStateException)
What should I do to overcome this?
Spawning a second thread using the code you gave above will work and run both threads in parallel. Something else must be going on to stop it working.
Make sure you have a try-catch around your do work and log any errors. Are both threads trying to write to the same file and the second one failing because it cannot?
For the actual thread you cannot start a thread again once it has exited, instead you need to keep the thread alive and run it in a loop. The thread should go to sleep when it is no longer needed, waiting for a message to arrive giving it new work to do. This can be done using something like a BlockingQueue.
Alternatively rather than managing threads yourself you can use something like a ThreadPoolExecutor and keep sending your Runnables to that.

Android/Java thread sleeping

Alongside the implicit User Interface thread, i have made two threads (runnables), both having a while loop inside them in which i periodically check for updates inside a message queue which I've implemented.
The problem at first was that the two while loops were infinite, and they changed so quickly and so much that they used up almost all the CPU of the device.
So i thought about making the while loops sleep for about 100 milisec after each cycle, to let the other threads do their work, but i came across another issue:
NOW, the problem is that the threads sleep for 100 milliseconds, but they don't let the UI thread work during that time :( And what this does is make the UI laggy. When i drag something on the screen it lags a bit.
So what i want to do is make these threads (these while loops) check the message queue flag every 100 miliseconds, but during those 100 miliseconds i want to let the UI thread run. How can this be accomplished?
EDIT 1
I found the yield method, which stops the running of the current thread, but when do i call this? I would need to call the sleep thread and at the same time make it yield somehow ... ??
EDIT 2
The two classes are singletons, and i start them from the first Activity of the application, so when the app starts (the UI thread)
//Obtain object of singleton classes
ControllerSingleton controller = ControllerSingleton.getControllerSingleton();
OpponentSingleton opponent = OpponentSingleton.getOpponentSingleton();
//Start threads
/*--------CONTROLLER----------*/
Thread t;
t = new Thread( controller );
t.setName("ControllerThread");
Log.i("Remy","Starting Controller thread...");
t.start();
/*--------OPPONENTS----------*/
t = new Thread( opponent );
t.setName("OpponentThread");
Log.i("Remy","Starting Opponent thread...");
t.start();
And inside each run() i have the next code:
public void run()
{
while( true )
{
//Check if any messages in the queue
if ( queueEmpty() == false )
{
//Do something ...
}
/*HERE IS WHERE I WOULD LIKE TO TELL THE THREAD TO STOP AND WAIT FOR 100 ms*/
}
}
I think that the thing you need to use is Handler. You might want to see this tutorial for example.

Categories