Stop ScheduledExecutorService after it runs two times? - java

I'm trying to have some code to be executed only 2 times with a delay of 500 microseconds between each execution.
So far I have used the ScheduledExecutorService and an int counter to track how may times the ExecutorService has run my code, but I want know if this is a good approach and if there is better way:
private void dingdong() {
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
exec.scheduleAtFixedRate(new Runnable() {
int count;
#Override
public void run() {
count++;
//TODO operation
if (count == 2) {
exec.shutdownNow();
}
}
}, 0, 500, TimeUnit.MICROSECONDS);
}

I think the ExecutorService is overkill. If you just use a normal Thread, it can run your operation, sleep, and run it again.
new Thread(() -> {
doTheThing();
TimeUnit.MICROSECONDS.sleep(500);
doTheThing();
}).start();

Related

How to schedule a periodic task but stop and return result if a condition is fulfilled (Java)

I need to execute a certain task periodically within a certain timeout.
But dependent on the result of the task, I want to stop before the end of the timeout is reached. And in addition I need a reference to the currently executed task in order to have the chance to ask for the result.
Solution to 1) is no problem, because it can be solved with the little code snipped shown below. But I can not figure out how to integrate 2). So with this code example, I would like that the beeper object runs code which can have a positive or a negative result and based on (for example) a positive result, the beeper task should no longer be executed periodically.
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);
}
}
In your run method if condition is fulfilled then invoke scheduler.shutdown(). That should do exactly what you want.
public void beepForAnHour() {
final Runnable beeper = new Runnable() {
public void run() {
System.out.println("beep");
if(isMyCondition() {
scheduler.shutdown();
}
}
};
See javadoc for ExecutorService.shutdown()

What is the best way to spawn a Thread with an infinite loop in Java 8?

I have a method that needs to be called every n seconds. In the old days of Java, I would do something like this:
Runnable task = () -> {
while (!updater.isInterrupted()) {
//some Task
} catch (InterruptedException e) {}
}
};
Thread updater = new Thread(task);
updater.start();
}
But this is obviously a bad idea. If I want to stop the Thread, I need to call updater.interrupt() and rely on exception handling which is actually not made for this stuff.
So I guess there's some fancy "new" Java8 way of doing this.I've seen this:
public class TestSchedularService {
long sleep = 500;
#Test
public void testLoop2() throws Exception {
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture future = executor.scheduleWithFixedDelay(new PollingService(), 0, sleep,TimeUnit.MILLISECONDS);
Thread.sleep(2 * sleep);
future.cancel(false);
executor.shutdown();
}
}
class PollingService implements Runnable {
private int count = 0;
public void run() {
System.out.println("iteration :" + (count++));
}
}
but it seems like it's creating an instance of PollingService on every call which seems to be bad. So what's the most efficient and "up to date" way of calling a method every n seconds?
Using ScheduledExecutorService is correct way. It doesn't create new instance of PollingService, you create it and the executor calls run on the same instance all the time until you cancel the Future.

Each thread should run for 10 minutes and then interrupt the thread if the time is over

I am trying to make an ExecutorService implementation that can be provided with a timeout or interrupt for each thread.
In my below example, suppose I am spawning 2 threads (in actual scenario, this number will be high), then I need to make sure each thread should be running for 10 minutes.
That means, Thread1 will run for 10 minutes and Thread2 will run for 10 minutes as well. If 10 minutes is over then I need to interrup the thread or timeout.
Below is the code I have so far and I am not able to understand how should I add this interrupt or timeout functionality here in such a clean way so that if I am making this no of threads parameter configurable in my code then it should work properly there as well.
public static void main(String[] args) {
final int noOfThreads = 2;
final long exp_time_millis = 600000; //10 minutes
//create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(noOfThreads);
for (int i = 0, i< noOfThreads; i++) {
service.submit(new ThreadTask());
}
}
class ThreadTask implements Runnable {
#Override
public void run() {
while(true) {
System.out.println("Thread running...");
try {
/* make a select sql to the database
* and measure how much time it is taking in
* returning the response
*/
} catch (InterruptedException e) {
}
}
}
}
Any suggestions will be of great help.
I have already seen few articles on the SO but I was not able to find anything which matches my scenario and I can implement that easily.
Updated Code:-
I am trying the below code but it gives me error on the catch block in the run method. Not sure if I am doing anything wrong. Can anyone help me?
public class ThreadTimeout {
public static void main(String[] args) {
final int noOfThreads = 2;
//create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(noOfThreads);
ScheduledExecutorService scheduleService = Executors.newScheduledThreadPool(noOfThreads);
for (int i = 0; i< noOfThreads; i++) {
final Future future = service.submit(new ThreadTask());
scheduleService.schedule(new Runnable(){
public void run(){
future.cancel(true);
}
}, 10, TimeUnit.MINUTES);
}
}
}
class ThreadTask implements Runnable {
#Override
public void run() {
//make a database connection
while (true) {
System.out.println("Thread running...");
try {
/*
* make a select sql to the database and measure
* how much time it is taking in returning the
* response
*/
} catch (InterruptedException e) {
}
}
}
}
I would recommend using a second ScheduledExecutorService. You can submit the Future returned from your original submissions to the ScheduledExecutorService to cancel.
ScheduledExecutorService scheduleService = Executors.newScheduledThreadPool(n);
for (int i = 0, i< noOfThreads; i++) {
final Future future = service.submit(new ThreadTask());
scheduleService.schedule(new Runnable(){
public void run(){
future.cancel(true);
}
}, 10, TimeUnits.MINUTES);
}
Now the ThreadTask needs to respond to interruption or else this will not help.
What I would recommend is to use the ExecutorService.awaitTermination(...); method and then the ExecutorService.shutdownNow() method.
For example:
for (int i = 0; i < noOfThreads; i++) {
service.submit(new ThreadTask());
}
// we always need to shutdown the service _after_ we've submitted all jobs
service.shutdown();
// now we wait for those tasks to finish for 10 minutes
if (!service.awaitTermination(10, TimeUnit.MINUTES)) {
// if we timed out waiting for the tasks to finish, forcefully interrupt them
service.shutdownNow();
}
Note that this will interrupt the threads but that will only cause certain methods such as Thread.sleep(), Object.wait(), and some others to throw InterruptedException. It also sets the interrupt bit on the thread which can be tested with Thread.currentThread().isInterrupted(). It will not "kill" the thread like you would a unix process.

Run thread only for one minute in java

What the best practice to run thread only for some period?
I can easily check curentTime and close the thread after in worked for some time, but I think it's not the right way.
It depends on what you want to achieve, but generally speaking the approach you mentioned with measuring the time from the start is not that wrong.
I would code it like this:
private static class MyTimerTask extends TimerTask {
private final Thread target;
public MyTimerTask(Thread target) { this.target = target; }
public void run() {
target.interrupt();
}
}
public void run() {
Thread final theThread = Thread.currentThread();
Timer timer = new Timer();
try {
timer.schedule(new MyTimerTask(theThread), 60000});
while(!theThread.interrupted()) {
....
}
} finally {
timer.cancel();
}
}
... which is Hovercraft described, except using interrupt instead of an ad-hoc flag. Using interrupts has the advantage that some I/O calls are unblocked by an interrupt, and some libraries will respect it.
I'm surprised (and deeply disappointed) that no one has mentioned the Executors framework. It has usurped the Timer framework (or at least the java.util.Timer class) as the "goto" for scheduled tasks.
For instance,
// Start thread
final Thread t = new Thread(new Runnable(){
#Override
public void run(){
while(!Thread.currentThread().isInterrupted()){
try{
// do stuff
}
catch(InterruptedException e){
Thread.currentThread().interrupt();
}
}
}
});
t.start();
// Schedule task to terminate thread in 1 minute
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
exec.schedule(new Runnable(){
#Override
public void run(){
t.interrupt();
}
}, 1, TimeUnit.MINUTES);

Synchronize two timers with multiple instances (Java)

I'm a newbie in Java and I haven't work with threads in past. Now I have a really tricky issue for my level of knowledge.
I have developed two functionalities the "Send mail" and the "Check mail". Each user register his preferences and the system creates two catalogues with many instructions for periodic work like
A) send message every 1500 msec
B) send message every 1800 msec
C) send message every 3000 msec
And
A) check message every 2000 msec
B) check message every 6000 msec
C) check message every 8000 msec
I tried many ways with threads but I fail to do it work.
My question is which is the best way to synchronize them? Below is code from my last effort using threads.
public class MailCreatorThread extends Thread {
#Override
public void run() {
CreateMail(_date); //creates a mail with _date as subject
}
}
public class GPSThread extends Thread {
#Override
public void run() {
// TODO Auto-generated method stub
while (!_isTimeToStop) {
try {
while (_servicesToUpdate.size() == 0) {
Thread.sleep(500);
}
_currentService = (MyService) _servicesToUpdate.get(0)
.clone();
_servicesToUpdate.remove(0);
MailCreatorThread mailCreatorThread = new MailCreatorThread();
mailCreatorThread.start();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class CheckServicesThread extends Thread {
#Override
public void run() {
// TODO Auto-generated method stub
while (!_isTimeToStop) {
try {
Thread.sleep(1000);
for (int j = 0; j < _servicesList.length; j++) {
MyService currentService = ((MyService) _servicesList[j]);
if (myService.getTimeToNextUpdate() - 1000 <= 0) {
_servicesToUpdate
.add((MyService) currentService
.clone());
currentService
.setTimeToNextUpdate(currentService
.getUpdatePeriod());
} else {
currentService
.setTimeToNextUpdate(currentService
.getTimeToNextUpdate() - 1000);
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
stopSelf();
}
}
You can use a ScheduledExecutorService to run thos periodic tasks. The syntax is fairly straightforward:
Runnable check = new Runnable() {
public void run() {
checkMessage();
}
}
Runnable send = new Runnable() {
public void run() {
sendMessage();
}
}
//since what you are doing is mostly I/O you probably want to have
//more than one thread available so that if one operation blocks,
//the other ones can be launched in parallel
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(10);
scheduler.scheduleAtFixedRate(check, 0, 1500, MILLISECONDS);
scheduler.scheduleAtFixedRate(send, 0, 6000, MILLISECONDS);
Note: Timer mentioned in Ozzy's answer should not be used any more as it has been improved in Java 1.5 by ScheduledThreadPoolExecutor, as explained in Timer's javadoc :
Java 5.0 introduced the java.util.concurrent package and one of the concurrency utilities therein is the ScheduledThreadPoolExecutor which is a thread pool for repeatedly executing tasks at a given rate or delay. It is effectively a more versatile replacement for the Timer/TimerTask combination, as it allows multiple service threads, accepts various time units, and doesn't require subclassing TimerTask (just implement Runnable). Configuring ScheduledThreadPoolExecutor with one thread makes it equivalent to Timer.
In java you have built-in Timer and TimerTask classes to help you repeat a task in a separate thread.
This will create a Timer which will create its own background Thread:
Timer t = new Timer();
You can then schedule as many tasks as you want to that timer, they will share the timer's own thread.
This is how you can schedule a single task on the timer thread, after a delay of 2000ms = 2s:
t.schedule(new TimerTask() {
#Override
public void run() {
//task to perform
}
}, 2000);
This is how you can schedule a repeated task on the timer thread, after a delay of 1s, and repeat the task at 1.5s intervals:
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
//task to perform every 1.5 seconds
}
}, 1000, 1500);
Now you have a choice to schedule both tasks (checkMail, sendMail) to the same Timer (same thread) or give them each their own Timer (separate threads).
For more info, refer to the java docs (http://docs.oracle.com/javase/6/docs/api/java/util/Timer.html)
Hope this helps.

Categories