ExecutorService.scheduleAtFixedRate to run a task forever

I want the task to run forever after an interval of 1 minute. To accomplish this, I wrote my task in

public void poll() { ScheduledExecutorService executorService= Executors.newScheduledThreadPool(1); ScheduledFuture files=executorService.scheduleAtFixedRate(new Runnable() { @Override public void run() { String path="/Desktop/PNL/Test"; List<String> filesPaths= new ArrayList<String>(); File folder= new File(path); File[] listOfFiles= folder.listFiles(); for (File file : listOfFiles) { filesPaths.add(file.getAbsolutePath()); } if(!CollectionUtils.isEmpty(filesPaths)){ try{ update(filesPaths); } catch(Exception e){ System.out.println(e.toString()); } } } }, 0, 1, TimeUnit.MINUTES); files.cancel(false); //executorService.shutdown(); } 

But the task is performed only once, and not after every minute. I do not understand what is wrong here.

+5
source share
4 answers

During the execution of your code in for (File file : listOfFiles) { a NullPointerException occurred that killed the thread.

The following change launched it continuously:

 if (listOfFiles != null) { for (File file : listOfFiles) { filesPaths.add(file.getAbsolutePath()); } } 

In addition, files.cancel(false) terminates execution. Therefore, I had to comment on this line. Link Future.cancel ()

+2
source

Tested code. As others suggest, the result is: Deleting a row

 files.cancel(false); 

makes it run every minute. Otherwise, it starts only once.

Here is my code for a test that works:

 import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; public class PeriodicCall { public static void main(String args[]) { new PeriodicCall().poll(); } public void poll() { System.out.println("poll"); // called once ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1); ScheduledFuture<?> files = executorService.scheduleAtFixedRate(new Runnable() { public void run() { System.out.println("running"); } }, 0, 1, TimeUnit.MINUTES); //files.cancel(false); //executorService.shutdown(); } } 

My run () function only contains System.out.println, so you should check your code inside the run () method. If it contains errors, it will abort everything.

+1
source

EDIT: after playing in a small sandbox for a minute, I rebuilt your code to work like this

 public static void main(String[] args) { ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1); Runnable files = new Runnable() { @Override public void run() { // Replace with your original code.. this was just a test to make sure it worked System.out.println("Hello"); } }; // Set this back to minutes, seconds was easier to test ScheduledFuture<?> scheduledFuture = executorService.scheduleAtFixedRate(files, 0, 1, TimeUnit.SECONDS); } 
0
source

I bet you get an unchecked exception in your Runnable. The following code prints "Running" exactly once:

 import java.io.*; import java.util.concurrent.*; public class Foo { public static void main(String[] args) { ScheduledExecutorService executorService= Executors.newScheduledThreadPool(1); ScheduledFuture files=executorService.scheduleAtFixedRate(new Runnable() { @Override public void run() { System.out.println("Running"); throw new RuntimeException("bar"); } }, 0, 1, TimeUnit.SECONDS); } } 

You should put a try / catch block around everything in your run() method and see what you catch.

  @Override public void run() { try { System.out.println("Running"); throw new RuntimeException("bar"); } catch (RuntimeException e) { // Do something better here, but for the sake of highlighting the issue: e.printStackTrace(); } } 
0
source

Source: https://habr.com/ru/post/1232600/


All Articles