The tile does not describe it properly so im going to try and describe it here:
I have a bukkit plugin, its a minigame.
It must have some code run for 10 minutes and then run another code until that game is finished
I currently have this:
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
// code for 10 minutes
}
}, 600000);
//code for after
Yet, this is only affects a single player and not that world.
So if one player joins he will wait 10 minutes and then run the otherpart of the code and so on, when the purpose is the 10 minutes start couting on their own, even if there is no player.
Thanks
Your problem is probably caused because your code is all triggered by an event?
Meaning it will only ever effect the player that triggered that event.
Instead you need a generic plugin that does not trigger on events (except for login), but instead it uses a timer and then grabs a list of all players and runs your code on each/all of them. Then after 10min it will exit to your other code and run that for the rest of the time.
Edit: rough example:
import org.bukkit.plugin.java.JavaPlugin;
public final class {$PluginName} extends JavaPlugin {
#Override
public void onEnable() { //This should proberbly be done onCommand rather than onEnable
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
long time = System.currentTimeMillis();
while (some condition....){
//load list of players
//now iterate through player list and do your code
//check if 10min has passed:
if ((System.currentTimeMillis() - time) > 600000){
//now break the loop and run your other code for the rest of the minigame
break;
}
}
//code for the rest of the minigame
while (true){
//load list of players
//now iterate through player list and do your code for the rest of the time
}
}
});
thread.start();
}
}
Related
I want to generate random number after every 2 seconds in my java (Android) program continuously for at least 10 minutes. But I just want to pause/delay execution of code in only one method and not the whole program.
I tried using Thread like this -
boolean stop = false;
int random_number = 0;
while(true){
if(stop){ //if stop becomes true, then
return; //terminate the method
}
random_number = Math.random(); //generate random number
//which is used bu some other
//part of code
try {
Thread.sleep(2000); //delay the code for 2 secs
} catch(InterruptedException ex) { //and handle the exceptions
Thread.currentThread().interrupt();
}
}
However, this doesn't work as Thread.sleep stop the whole program execution instead on just stopping execution of code inside method and my whole screen becomes blank.
I also tried using Handler but it didn't work either as it doesn't stop execution of code in my method and instead just stack up.
This will demonstrate the working of it better -
while(true){
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
System.out.println("After 2 secs"); //this gets printed
//later
}
}, 2000);
System.out.println("Before 2 secs"); //this gets printed first
}
So the code stacks up making it equivalent to using while loop and make it incredibly slow.
Also, since I'm developing app for Android, I'm running on Java SE 6, so I can't use scheduleAtFixedRate. Is there any other way in which I can accomplish this?
Thanks a lot!
private Timer timer;
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
//Generate number
}
}, 2000, 2000);
//Documentation (From SDK)
/**
* Schedule a task for repeated fixed-rate execution after a specific delay
* has passed.
*
* #param task
* the task to schedule.
* #param delay
* amount of time in milliseconds before first execution.
* #param period
* amount of time in milliseconds between subsequent executions.
public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
if (delay < 0 || period <= 0) {
throw new IllegalArgumentException();
}
scheduleImpl(task, delay, period, true);
}
and when you want to stop it
timer.cancel()
Option 1: Using threads, you might run your job off the main (UI) thread:
new Thread(new Runnable() {
// some code here ...
// This might be in a loop.
try {
Thread.sleep(2000);
} catch(InterruptedException ex) {
// Handle ...
}
}
}).start();
Then, if this new thread you'd like to modify UI (i.e. show/hide button, display something on the screen etc), remember to pass that through the UI thread, as only this one can modify the UI. You might consider using Activity.runOnUiThread() for that.
Option 2: Another, more Android-style way of approaching that issue is to use AsyncTask. It contains three callbacks which can be used to do work on- and off- the UI thread. Sketch of such a code could look like:
private class MyTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... param) {
// This method is running off the UI thread.
// Safe to stop execution here.
return null;
}
protected void onProgressUpdate(Void... progress) {
// This methid is running on the UI thread.
// Do not stop thread here, but safe to modify the UI.
}
protected void onPostExecute(Long result) {
// Also on UI thread, executed once doInBackground()
// finishes.
}
}
Option 3: Then there is also a Timer, as suggested by #Stultuske. It's less flexible then AsyncTask, but handles the interval for you.
Depending on your needs, you can still accomplish what you seek with Handler.
You don't have to create/start the Handler in a while loop(which, as you noticed, just stacks up unless you stop the loop itself, but it is a nonsense).
Just create the Handler and tell him to post delayed your Runnable instance. In the Runnable at the very end you check your conditions. If it is still OK, then post another runnable delayed, else you do nothing and the Handler will have no more executions.
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
System.out.println("After 2 secs");
random_number = Math.random();
if (!stop) // should not be stopped, so we add another runnable;
{
handler.postDelayed(this, 2000);
}
}
handler.postDelayed(runnable, 2000);
The only downside is that Handler could freeze if the device is not used for a while, meaning it will start the counting back from where it left once the device screen is turned on.
It could do like 1 minute of correct work, then block at 1.4 seconds when the device is gone in sleep mode, and once it is turned on again, Handler would do the remaining 0.6 seconds.
Still, not knowing your needs you may be unaffected by this behavior and the answer may fit you.
if you want to use thread, do it like this :
Thread t = new Thread(){
public void run(){
while(true){
if(stop) break;
random_number = Math.random();
sleep(2000);
}
}
};
t.start();
I'm working on a text adventure game for my Java class, and I'm running into a problem while trying to time a print statement from showing up in the console.
Basically after 45 seconds I would like a print statement to show up, in this case the print statement would be reminding the user that they need to let their virtual dog out...
I also need the timer to reset after the user gives the correct command.
import java.util.Timer;
import java.util.TimerTask;
...
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
System.out.println("delayed hello world");
}
}, 45000);
Timer
TimerTask
To cancel the timer, either use a TimerTask variable to remember the task and then call its cancel() method, or use timer.purge(); the latter cancels all tasks on the timer. To schedule the task again, just repeat.
You'll probably want to do more advanced operations in the future, so reading the Timer API docs is a good idea.
Timer timer = new Timer();
timer.schedule(new TimerTask(){
public void run() {
System.out.println(" let the virtual dog out ");
}
}, 45000);
Try running in a new Thread.
new Thread(new Runnable()
{
public void run()
{
Thread.sleep(45000);
System.out.println("My message");
}
})
.run();
This should work.
Just tell the thread to sleep for 45 seconds, there is a tutorial here:
http://docs.oracle.com/javase/tutorial/essential/concurrency/sleep.html
Tell the main thread to sleep might not be ideal as it will cause your program to basically stop. Use a another thread(need to do a little multi-threading) for timing your output and do a check if the message should be printed after the 45s.
After creating a session, i want to call a method again & again after a specific time - i.e. 5 sec.
But when i call a method it gives me an error. Here is the sample code.
public class RunFunction extends MainScreen{
public RunFunction()
{
//Call Function again and again after 5 sec
setTitle("Timer");
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
BasicEditField b = new BasicEditField("Hello", "");
String a = b.getText();
Dialog.alert("Value " +a);
}
}, 5000);
}
}
I need help related to this. Can you provide any sample code?
From the BlackBerry docs on the Timer class:
A facility for threads to schedule tasks for future execution in a background thread.
So, the first thing to understand is that whatever work you do in the run() method will be run on a background thread. Background threads are not allowed to modify the UI directly. You're probably getting an IllegalStateException by doing that.
Maybe this is just test code, but this code
BasicEditField b = new BasicEditField("Hello", "");
String a = b.getText();
Dialog.alert("Value " +a);
is a little confusing. It creates a BasicEditField, but only uses it to get the String value passed in to it. Just instantiating a field does not add it to a screen. So, you would need to call
add(b);
after this code for the edit field to show. But again, that would be modifying the UI directly. So, in your case, you probably just need to wrap your code with a call to UiApplication#invokeLater():
timer.schedule(new TimerTask() {
public void run() {
// this code executed on background thread -> not UI safe!
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
// this code safely executed on UI thread
BasicEditField b = new BasicEditField("Hello", "");
add(b);
String a = b.getText();
Dialog.alert("Value " +a);
}
});
}
}, 5000);
Next, calling Timer#schedule(TimerTask,long) will only schedule your task to run once, after 5000 milliseconds. If you want it to run again and again, use the version of schedule(TimerTask,long,long) that takes three parameters. The last parameter is the amount of time between each call to your timer task's run() method.
This example on Timer and TimerTask java class provides some insights on what you want to do:
http://javaprogramming.language-tutorial.com/2012/02/demonstrate-timer-and-timertask.html
I am trying to simulate a live data stream, to test a program that is constantly filtering and computing data points. Mainly I need to make sure that it will meet timing.
Every 50 milliseconds there will be a new data point that will need to be computed on.
So I would like to create a java clock that is independent of what is currently running in the jvm or anything like that happening on the system.
So my question is two fold:
first of all, System.currentTimeMillis() will not be what I want here because it is based on when the jvm was opened, and it would happen when ever the system call gets executed.
second, how do i make a thread that will be constantly running and always trigger exactly on the 50ms mark?
There's pretty good, pre-defined mechanism (comparing to pure threading) of Timers and TimerTask:
import java.util.Timer;
import java.util.TimerTask;
public class Reminder {
Timer timer;
public Reminder(int seconds) {
timer = new Timer();
timer.schedule(new RemindTask(), seconds*1000);
}
class RemindTask extends TimerTask {
public void run() {
System.out.format("Time's up!%n");
timer.cancel(); //Terminate the timer thread
}
}
public static void main(String args[]) {
new Reminder(5);
System.out.format("Task scheduled.%n");
}
}
(took from: http://enos.itcollege.ee/~jpoial/docs/tutorial/essential/threads/timer.html)
This mechanism allows you to execute your code in RemindTask's run() method every 5 seconds (that value was specified in code)
Take a look at ScheduledExecutorService, more specifically the scheduleAtFixedRate() method.
It allows you to perform an operation at regular intervals.
Take a look at ScheduledExecutorService.
Here is an example:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(new Runnable() {
public void run() {
//New data point
}
}, 0, 50,TimeUnit.MILLISECONDS );
I'm trying to use Timer in my BlackBerry project in this manner -
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
pushScreen(new MyScreen());
}
},200);
but I'm getting a Runtime Exception while executing the program.
Can someone please tell me what is wrong with this code? Or any other tips for using the Timer in a BlackBerry project.
My goal is to push SplashScreen for 10 sec and then MyScreen page will be open. So I want to use timer for a 10 second delay while opening the MyScreen page and during the timer I will display the SplashScreen page.
As Richard mentioned in his answer, you are having problems because you're attempting to manipulate the UI from a thread other than the main (aka "UI") thread. You just need a small change to make your code work properly:
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
pushScreen(new MyScreen());
}
},
200 /* delay */,
false /* repeat = no */);
The above is the equivalent of the code you posted, for BlackBerry Java.
My goal is to push SplashScreen for 10 sec and then MyScreen page will
be open. So I want to use timer for a 10 second delay while opening
the MyScreen page and during the timer I will display the SplashScreen
page.
If this is actually what you want to do, then just make your SplashScreen appear as soon as the app is launched:
public class MyApp extends UiApplication
{
/**
* Entry point for application
* #param args Command line arguments (not used)
*/
public static void main(String[] args)
{
// Create a new instance of the application and make the currently
// running thread the application's event dispatch thread.
MyApp theApp = new MyApp();
theApp.enterEventDispatcher();
}
public MyApp()
{
// Push a screen onto the UI stack for rendering.
final SplashScreen splashScreen = new SplashScreen();
pushScreen(splashScreen);
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
pushScreen(new MyScreen());
popScreen(splashScreen);
}
},
10*1000 /* delay in msec */,
false /* repeat = no */);
}
This does what you asked, but the link that Richard provides also allows the user to dismiss the splash screen early. That may or may not be what you want, so I simply offer the alternative above.
Hard to say what exactly is going wrong, but one thing that you should not do is interact with the user interface on a thread that is not the event thread.
It won't teach you how to use timers but there is a developer article on how to do a splash screen.
You're pushing a new screen every 200 ms...
You need to kill the timer when the screen is pushed. And remember that the interval is in milliseconds, so you need to calculate that.
Good luck!
For Android you would probably want to do something like this:
initialize();
setButtonListeners();
new Thread() {
public void run() {
try {
sleep(3000);
} catch (Exception e) {
} finally {
Intent menuIntent = new Intent(SplashLoadScreen.this,
MainMenu.class);
startActivity(menuIntent);
}
}
}.start();
I'm not too familiar with BlackBerry, but it seems like you use pushScreen() instead of startActivity(), and you don't use Intents like Android does, so perhaps something as this:
initialize(); //Method to initialize all variables you might want to use.
//...Some code
new Thread() {
public void run() {
try {
sleep(3000); //Time in milliseconds
//to make this thread sleep before executing whatever other code.
} catch (Exception e) {
} finally {
pushScreen(new MyScreen()); //Push next screen
}
}
}.start();
The try{} catch(){} finally{} thing is exception handling.
Basically, if any errors happen when it's attempting to sleep for 3000 millis, then it will catch all Exceptions (a.k.a. errors) and do whatever's in catch(){}. Then, after either the try {} (if no exceptions have been found) or the catch(){} (if errors have been found) is finished, it does whatever's in the finally{}. This case finally will push the next screen.