I am writing a minigame for Minecraft and have a problem with the schedule. I don't know how to stop the schedule. Please tell me how I can stop running this loop / Timer / Schedule:
public void WarteTimer() {
count = Bukkit.getScheduler().scheduleSyncRepeatingTask(
(Plugin) this,
new Runnable() {
#Override
public void run() {
if (countdown > 0) {
Bukkit.broadcastMessage("ยง6Countdown : " +countdown);
countdown--;
} else {
Game();
//Bukkit.getScheduler().cancelTask(count);
//countdown = 5;
}
}
},
0L,
20L);
}
To stop a scheduler in bukkit you have to get the id for the scheduler and call the Bukkit scheduler cancel method.
I see you have already set count equal to the scheduler. I am assuming count is an integer.
To stop a scheduler simply put:
Bukkit.getScheduler().cancelTask(taskID);
In your case you will use :
Bukkit.getScheduler().cancelTask(count);
You can run this line where ever and it will stop your scheduler.
Related
I want to Schedule a job to run at multiple of 2 seconds, which is 2,4,8,16,32 seconds. Second fire should happen after two seconds of completion of first fire, Third fire should happen after 4 seconds of completion of second fire and so on. The next fire is based on status we get from previous fire, based on which it will be decided whether we need to trigger next fire or not.
Can somebody tell me how can I use quartz scheduler to achieve this?
If I use SimpleTrigger.withIntervalInSeconds(2) it runs a job after every 2 seconds where as I want time interval should be increased with multiple of 2 in every firing.
Perhaps you could forget trying to set up a single trigger, but use multiple triggers. My Java is not good in this area, so this is in pseudocode:
delay = 2
repeat
TriggerOnceAfter(delay)
delay <- delay * 2
WaitUntilTriggered()
until (finished)
I am not sure how to implement the WaitUntilTriggered() method; you my need to add a signalling flag to the triggered code for WaitUntilTriggered() to look at.
That will give delays of 2, 4, 8, ...
This is a simplified implementation that will invoke a Runnable at the requested schedule:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class Tasker {
private int numberOfRuns; //how many times job executed
private int timeBetweenRuns;//seconds
Tasker(int numberOfRuns){
this.numberOfRuns = numberOfRuns;
timeBetweenRuns = 2;
execute();
}
private void execute() {
for (int counter = 0; counter < numberOfRuns ; counter++) {
CountDownLatch latch = new CountDownLatch(1);
Job job = new Job(latch, timeBetweenRuns);
job.run();
try {
latch.await();
TimeUnit.SECONDS.sleep(timeBetweenRuns);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
timeBetweenRuns *=2;
}
}
public static void main(String[] args){
new Tasker(5);
}
}
class Job implements Runnable {
private int seconds;
private CountDownLatch latch ;
Job(CountDownLatch latch , int seconds){
this.latch = latch;
this.seconds = seconds;
}
#Override
public void run() {
System.out.println("Job runs "+ seconds +" after previous one");
latch.countDown();
}
}
I want to run repeated task 3 times only from a foreground service.
I tried to use ScheduledExecutorService
ScheduledExecutorService scheduler = Executors
.newScheduledThreadPool(1);
counter = 0;
scheduler.scheduleWithFixedDelay(new Runnable() {
public void run() {
if (counter<3) {
counter++;
System.out.println("Do something useful");
}
else {
scheduler.shutdownNow()
}
}
}
}, 2, 2, TimeUnit.SECONDS);
But im not sure if it's the right way to go with.
This repeated task will run only 3 times and will stop after that.
AlarmManager is another option but sounds to me like an overkill for this short period task.
Any advice would be helpful!
I'm trying to limit attempts of a process in a loop to 60 seconds by sleeping for 3,000ms per loop with 20 attempts. Calling Thread.sleep() isn't actually pausing execution in the thread that's running and instead, all 20 attempts happen rapidly in succession.
private void pollWebServiceForToken() {
final int pollInterval = 3000;
new Thread() {
#Override
public void run() {
int attempts = 0;
int maxAttempts = 60;
String token;
do {
token = requestToken(exchangeCode);
if (token.contains(FAILED)) {
try {
Thread.sleep(pollingInterval);
} catch (InterruptedException ex) {
this.currentThread().interrupt();
}
}
attempts++;
} while (token.toLowerCase().contains(FAILED) && attempts < maxAttempts && !cancelled);
}
}.start();
}
Since this is all happening inside of a Vaadin application, I'm assuming the wrong Thread is being put to sleep but I'm not sure how to target a specific thread for sleeping.
Thanks in advance
Are you sure the code inside the if is being run? The condition on the while is different (+toLowerCase). Thread.sleep() always causes the current thread to sleep.
I want to run java code for a certain duration ,say 16 hours! I have a java code that runs for approximately an hour.I want this to run repeatedly for 16 hours. So I have a parameter that is passed by the user through Jenkins ! I access this value using
System.getenv("Duration");
Now, I want to exit the execution after the specified time. So suppose the user selected 16, the script should run for 16 hours and then exit.
Accepting input from Jenkins user as shown in the image
I saw some other questions, but most of them were dealing with timers for either few seconds or few minutes. I need an efficient solution. Thanks :)
FYI - Environment - Jenkins+TestNG+Maven+Java
EDIT :
long start = System.currentTimeMillis();
long end = start + durationInHours*60*60*1000;
while (System.currentTimeMillis() < end)
{
//My code here runs for approx. 50 mins!
}
Now suppose the user chooses the value 3 hours, I want the while loop to exit after 3 hours. But this does not happen as it has not yet completed 3 hours when checking the while condition.So it enters the while condition even the 4th time(since time elapsed is 150 mins which is less than 180 mins) it ends after 3 hours ten mins.
How to make it exit the while loop as soon as 180 mins is reached ?
P.S - I could do the math first,( iterations =durationFromUser/codeDuration) and then run a for loop, but I don't want to do this as my script length may vary.
EDIT 2:
boolean alive = true;
Timer timer = new Timer();
#Test() //Annotation from TestNG
public void public void jenkinsEntryPoint()
{
String duration = System.getenv("Duration");
int durationInHours=Integer.parseInt(duration);
long end = System.currentTimeMillis() + durationInHours*60*60*1000;
TimerTask task = new TimerTask() {
public void run() {
alive = false;
};
timer.schedule(task, end);
while (alive) {
//My code here runs for approx. 50 mins!
function1();
}
}
void function1() {
function2();
}
private void function2() {
for(i=0;i<8;i++)
{
while(alive)
{
//long running code
sleep(1000);
//Some more code
sleep(2000);
//Some more code
//Suppose time elapses here, I want it to quit
//But its continuing to execute
.
.
.
.
}
}
}
The while condition will only be evaluated between script invocations (as you've seen). You will have to break out of your long running from inside of it.
I would typically use a Timer to set a "global" boolean that you would check from inside the loops in your long running code.
Something like this. Notice checks against 'alive' would have to be in all you long loops...
boolean alive = true;
Timer timer = new Timer();
public void jenkinsEntryPoint()
long end = System.currentTimeMillis() + durationInHours*60*60*1000;
TimerTask task = new TimerTask() {
public void run() {
alive = false;
};
timer.schedule(task, end);
while (alive) {
//My code here runs for approx. 50 mins!
yourLongRunningCode()
}
public void yourLongRunningCode() {
while (alive) {
doStuff();
}
}
I tried ScheduledThreadPoolExecutor and it worked!
ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
exec.scheduleAtFixedRate(new Runnable() {
public void run() {
System.out.println("Time's Up According To ScheduledThreadPool");
alive = false;
}
}, durationInHours, 1, TimeUnit.HOURS);
This function will be executed after "durationInHours".
Thanks #TedBigham :)
I need to create a java function that will only run for 30 minutes, and at the end of the 30 minutes it executes something. But it should also be able to self terminate before the given time if the right conditions are met. I don't want the function to be sleeping as it should be collecting data, so no sleeping threads.
Thanks
Use: Timer.schedule( TimerTask, long )
public void someFunctino() {
// set the timeout
// this will stop this function in 30 minutes
long in30Minutes = 30 * 60 * 1000;
Timer timer = new Timer();
timer.schedule( new TimerTask(){
public void run() {
if( conditionsAreMet() ) {
System.exit(0);
}
}
}, in30Minutes );
// do the work...
.... work for n time, it would be stoped in 30 minutes at most
... code code code
}
Get the start time with System.currentTimeMillis(), calculate the time when to stop and check the current time every now and then while you're collecting the data you want to collect. Another way would be to decouple the timer and the data collecting, so that each of them could run in their own threads.
For a more specific answer, it would be helpful if you would tell what data you are collecting and how you are collecting it.
Something like this will work:
long startTime = System.currentTimeMillis();
long maxDurationInMilliseconds = 30 * 60 * 1000;
while (System.currentTimeMillis() < startTime + maxDurationInMilliseconds) {
// carry on running - 30 minutes hasn't elapsed yet
if (someOtherConditionIsMet) {
// stop running early
break;
}
}
The modern java.util.concurrent way would be using ExecutorService. There are several invoke methods taking a timeout.
Here's a kickoff example:
public static void main(String args[]) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(new Task()), 30, TimeUnit.MINUTES);
executor.shutdown();
}
where Task look like this:
public class Task implements Callable<String> {
#Override
public String call() {
// Just a dummy long running task.
BigInteger i = new BigInteger("0");
for (long l = 0; l < Long.MAX_VALUE; l++) {
i.multiply(new BigInteger(String.valueOf(l)));
// You need to check this regularly..
if (Thread.interrupted()) {
System.out.println("Task interrupted!");
break; // ..and stop the task whenever Thread is interrupted.
}
}
return null; // Or whatever you'd like to use as return value.
}
}
See also:
Lesson: Concurrency