change code to repeat forever - java

class BeeperControl {
private final static ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
public static void main(String[] args){
beepForAnHour();
}
public static void beepForAnHour() {
final Runnable beeper = new Runnable() {
public void run() {
System.out.println(“beep”);
}
};
final ScheduledFuture beeperHandle =
scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
scheduler.schedule(new Runnable() {
public void run() {
beeperHandle.cancel(true);
}
}, 60 * 60, SECONDS);
}
}
This code beeps every 10 seconds for an hour. How do i make it beep for every 10minutes forever. as in it should keep beeping every 10mins forever(not just for an hour)

You explicitly schedule a cancel task. If you don't want to cancel, then don't schedule the cancelling task.

Just remove the 2nd schedule that does the cancel.

I propose:
public void run() {
while(true) {
System.out.println(“beep”);
Thread.sleep(10000);
}
}
+'s;
Simpler
You can track if you're being Interrupted
-'s:
- You have to catch the InterruptedException
If you want to stop:
Put code to stop/pause in the catch statement and say myThread.interrupt(); to stop, starting it again is a bit harder, your best option is to create a new Thread (that does exactly the same). Info here: How to start/stop/restart a thread in Java?
Put an if-statement in the while-loop, checking a public boolean isRunning, if it's false, say continue; an recheck again and again until it is true again, put your beeping code in the 'true-block'.

Related

How to properly kill my java program when a scheduled process is done?

I have a simple java program I use to generate elements and insert them in DB every X seconds during a specific time.
The generation is done with a scheduleAtFixedRate. there is only one of these.
I want my program to quit completely when the scheduled task is over. To do so, I use System.exit() when the task is canceled, but is it the correct way to do this ?
Here is my current code:
public static void main(String[] args) throws InterruptedException {
c = generateDbConnection(url, user, password);
if (c != null) {
s = generateDbStatement(c);
} else {
System.out.println("ERROR");
return;
}
initialTimestamp = new Date();
TimeUnit.SECONDS.sleep(1);
generateForAnHour();
}
private final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
/**
* Generator thread handler Uses Statement from main function
*/
public static void generateForAnHour() {
final Runnable runner = new Runnable() {
public void run() {
String[][] data = new String[numberOfIds][2];
for (int i = 0; i < numberOfIds; i++) {
data[i] = generateDevice();
insertDevice(s, data[i][0], data[i][1]);
}
quantityOfIds += numberOfIds;
}
};
final ScheduledFuture<?> generatorHandle = scheduler.scheduleAtFixedRate(runner, 0, 5, TimeUnit.SECONDS);
scheduler.schedule(new Runnable() {
public void run() {
generatorHandle.cancel(true);
System.out.println("Scheduled ID generator terminated.");
System.exit(0); //TODO Is it really correct way to do it
}
}, timeToRun, TimeUnit.SECONDS);
}
I am not sure if this is the correct way to stop the execution of your program if it has some more functions, but I, personally, find it an OK way. :D
So, as it turned out, ScheduledExecutorService seemingly creates non-daemon threads with its default ThreadFactory, perhaps we need to supply a daemonic one to it.
However, if we are to call ExecutorService#shutdown or the forceful ExecutorService#shutdownNow, it will stop both tasks from executing, thus removing the thread(s) that prevent the application from ending its job:
private final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public static void main(String[] args) {
// Some service code here
generateForAnHour();
}
public static void generateForAnHour() {
// Some code that does work
final Runnable runner = () -> System.out.println("Running...");
final ScheduledFuture<?> generatorHandle = scheduler.scheduleAtFixedRate(runner, 0, 1, TimeUnit.SECONDS);
// Code that interrupts the worker after a specified time
scheduler.schedule(scheduler::shutdown, 5, TimeUnit.SECONDS);
}
Output:
Running...
Running...
Running...
Running...
Running...
Running...
Process finished with exit code 0
I hope this will help. :D
This answer is secondary to this one, but it has a different way to solve the problem, so I thought it is appropriate enough to create a separate answer.
If you want to have some more tasks in the future, I believe this solution is more scalable and is more "correct thing".
It creates daemon threads for both runner and interrupter. I think it would be better to create a normal thread factory for the interrupter, but I failed to make it working, so it's better to stick to my first answer...
Here generateForAnHour returns a Future that is used to wait for the time needed.
private final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1 , new ThreadFactory() {
#Override
public Thread newThread(final Runnable r) {
Thread t = Executors.defaultThreadFactory().newThread(r);
t.setDaemon(true);
return t;
}
});
public static void main(String[] args) throws InterruptedException, ExecutionException {
// Some service code here
generateForAnHour().get();
}
public static ScheduledFuture<Boolean> generateForAnHour() {
// Some code that does work
final Runnable runner = () -> System.out.println("Running...");
final ScheduledFuture<?> generatorHandle = scheduler.scheduleAtFixedRate(runner, 0, 1, TimeUnit.SECONDS);
// Code that interrupts the worker after a specified time
return scheduler.schedule(() -> generatorHandle.cancel(false), 5, TimeUnit.SECONDS);
}
If you won't call Future#get, you'll receive only one Running... in best case or none at all.
If you decide to return the runner future, you'll probably get nasty CancellationException in the get() call:
Exception in thread "main" java.util.concurrent.CancellationException
at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:121)
at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
at com.xobotun.Test.main(Test.java:30)
I'd use the ExecutorService::shutdown approach as the stabler and more understandable one. :D

Creating a thread that will execute after delay

How would I create a thread that will execute after a delay of s seconds?
I would like other processes to run while the thread is waiting.
For example, I would like to create the thread, then print out several other strings, then after s seconds, the thread will run.
What I don't need is the whole program to wait for s seconds, then everything happens. I need processes to run while the delay is ticking.
Thanks!
~Java preferred
Use a ScheduledExecutorService. See the example below.
System.out.println("some stuff");
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
final Runnable task = new Runnable() {
#Override
public void run() {
System.out.println("do something");
}
};
Future<?> futureHandle = scheduler.scheduleWithFixedDelay(task, 10, 10, TimeUnit.SECONDS);
System.out.println("some other stuff");
The task is scheduled with a fixed delay of 10 seconds, so you'll get output for the print statements not in the Runnable followed by the one in the Runnable every 10 seconds.
The output in this example is
some stuff
some other stuff
do something
do something
...
with the "do something" lines occurring at 10 sec. intervals after an initial 10 sec. delay.
To stop it, you can create a "stop" task to put some kind of logic in, and register that.
final Runnable stopTask = new Runnable() {
#Override
public void run() {
futureHandle.cancel(true); // true: interrupt if necessary
}
};
long delay = // some number, how long to wait before invoking the stop task
scheduler.schedule(stopTask, delay, TimeUnit.SECONDS).get(); // wait if necessary and get the future result
scheduler.shutdown(); // shutdown on completion
EDIT
If you just need the task to run once, as pointed out in the comments, consider a TimerTask:
final Timer timer = new Timer();
final TimerTask task = new TimerTask() {
#Override
public void run() {
System.out.println("timer task");
timer.cancel(); // stop timer after execution
}
};
timer.schedule(task, 1000); // schedule task with delay of 1000ms
I would suggest you to take look into quartz scheduler. This is very powerful and does almost similar tasks like unix cron in java environment.
There are bunch of tutorials online for quartz that you can always look into.
Here is one working example with Thread.sleep():
public class DelayThread implements Runnable {
private final int DELAY;
public DelayThread(int delay) {
this.DELAY = delay;
}
#Override
public void run() {
try {
Thread.sleep(DELAY);
System.out.println("task executed");
} catch (InterruptedException ex) {
System.out.println("interrupted");
}
}
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new DelayThread(2000));
thread1.start();
Thread.sleep(500);
Thread thread2 = new Thread(new DelayThread(2000));
thread2.start();
System.out.println("All threads are started");
}
}

Cancel asynchronous calls

We need to implement a feature that allows us to cancel a future job. Given that this job is doing DB calls and we need to rollback\cleanup any updates made before cancel was fired.
This is what I have tried, but "Thread.currentThread().isInterrupted()" always return false:
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
final Future future = executor.submit(new Callable() {
#Override
public Boolean call() throws Exception {
// Do Some DB calls
if (Thread.currentThread().isInterrupted()) {
// Will need to roll back
throw new InterruptedException();
}
return true;
}
});
executor.schedule(new Runnable() {
public void run() {
future.cancel(true);
}
}, 1, TimeUnit.SECONDS);
Is this the right approach to achieve our target? And how to know if the job was cancelled in order to cancel\roll back changes?
I believe that you complete the database calls before the second task gets a chance to run. When you have only a single executor it is possible that it does not schedule time for the second scheduled task before the first completes. This following snippet does get interrupted:
import java.util.*;
import java.util.concurrent.*;
public class Main {
public static void main(String[] arg) {
ScheduledExecutorService runner = Executors.newScheduledThreadPool(2);
// If this is 1 then this will never be interrupted.
final Future f = runner.submit(new Callable<Boolean>() {
public Boolean call() throws Exception {
System.out.println("Calling");
while (! Thread.currentThread().isInterrupted()) {
;
}
System.out.println("Interrupted");
return true;
}
});
runner.schedule(new Runnable() {
public void run() {
System.out.println("Interrupting");
f.cancel(true);
}
}, 1, TimeUnit.SECONDS);
}
}
First it seems the thread pool is not creating new thread for you so your cancel task will get called only after the DB task finishes. So I changed the pool size in yours example to 2 and it worked.

How to run a method in Java using a timer?

How would I have this method run every couple of seconds in a recursive function.
I want the i variable to update by 1 every couple of seconds than print it to the console.
In javascript I could use setTimeout is there a method like the javascript setTimeout in Java?
final i = 0;
public void timerActions() {
i = i + 1;
System.out.println(i);
}
try with Timer
Timer timer = new Timer("Display Timer");
TimerTask task = new TimerTask() {
#Override
public void run() {
timerActions();
}
};
// This will invoke the timer every second
timer.scheduleAtFixedRate(task, 1000, 1000);
}
You should use ScheduledExecutorService for that.
Update per Peter Lawrey comment (thanks):
Methods :
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit);
and
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit);
can be used in order to achieve your desired behavior.
You can put the Thread to sleep after execution if it's just a simple application which just has to "run slower".
For example:
final i = 0;
public void timerActions() {
i++;
System.out.println(i);
Thread.sleep(1000);
}
1000 in the parentheses means 1000ms=1second - the amount of time in which the thread sleeps.
This is a simple way to do it, but be aware that in larger multi-threaded applications you have to take into acount thread safety and related problems.
Documentation for Thread.sleep()
public class TimedAction
{
public static void main(String[] args) throws Exception
{
System.out.println("begin");
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
Runnable command = new Runnable()
{
private int i = 0;
#Override
public void run()
{
// put your logic HERE
System.out.println(i++);
}
};
// execute command, immediately (0 delay), and every 2 seconds
executor.scheduleAtFixedRate(command, 0, 2, TimeUnit.SECONDS);
System.in.read();
executor.shutdownNow();
executor.awaitTermination(5, TimeUnit.SECONDS);
System.out.println("end");
}
}
This will print "Counting..." on every 2 seconds
import java.util.Timer;
import java.util.TimerTask;
public class MyTimerTask extends TimerTask {
private int counter = 0;
public void run() {
counter++;
if (counter <= 3) {
System.out.println("Counting - counter = " + counter);
} else {
System.out.println("Stopping timer execution");
this.cancel();
}
}
public static void main(String[] args) {
Timer timer = new Timer("TimerThreadName");
MyTimerTask task = new MyTimerTask();
// void java.util.Timer.schedule(TimerTask task, long delay, long period)
timer.schedule(task, 0, 2000);
}
}

JAVA: what is the best way for scheduling Thread works?

I need to make a Thread which starts it's work at the time the program runs and dies when the program is closed. this Thread is going to check something every 1 minute ones.
what is the best way for this scheduling, using Thread.sleep() or using a Timer or what?
You've not provided any code, but there's loads of examples about for this sort of thing, here's one:
import static java.util.concurrent.TimeUnit.*;
class BeeperControl {
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
public void beepForAnHour() {
final Runnable beeper = new Runnable() {
public void run() { System.out.println("beep"); }
};
final ScheduledFuture<?> beeperHandle =
scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
scheduler.schedule(new Runnable() {
public void run() { beeperHandle.cancel(true); }
}, 60 * 60, SECONDS);
}
}
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ScheduledExecutorService.html#scheduleAtFixedRate(java.lang.Runnable
Create a ScheduledExecutorService throught Executors#newSingleThreadScheduledExecutor()
Schedule your thread with ScheduleExecutorService#scheduleAtFixedRate
At the end of your application, call ScheduledExecutorService#shutdownNow()
So you will have something like
public class Application {
private final ScheduledExecutorService executor;
private final Runnable task;
public Application(ScheduledExecutorService executor, Runnable task) {
this.executor = executor;
this.task = task;
}
public void init() {
executor.scheduleAtFixedRate(task, 0, 60, TimeUnit.SECONDS);
}
public void shutdown() {
executor.shutdownNow();
}
}
and you will create your application with something like
// ....
Application app = new Application(Executors.newSingleThreadScheduledExecutor(), task);
app.init();
// ....
// at end
app.shutdown();
To make a Thread which starts it's work at the time the program runs and dies when the program is closed, mark this thread as a daemon thread:
Thread myThread=new Thread();
myThread.setDaemon(true);
myThread.start(); // forget about it, no need to explicitly kill it

Categories

Resources