Steve Chambers Steve Chambers - 1 month ago 8
Java Question

How to implement a fixed rate poller with ScheduledExecutorService?

Given the following class:

public class Poller implements Runnable {
public static final int CORE_POOL_SIZE = 4;

public boolean running;
public ScheduledExecutorService ses;

public void startPolling() {
this.ses = Executors.newScheduledThreadPool(CORE_POOL_SIZE);
this.ses.scheduleAtFixedRate(this, 0, 1, TimeUnit.SECONDS);
}

public void run() {
running = true;
// ... Do something ...
running = false;
}
}


The
ScheduledExecutorService
has a core thread pool size of 4 but will more than one poller thread ever be created? Since
this
is passed into
scheduleAtFixedRate
does that mean there will only ever be one thread - or does something more complex happen behind the scenes?

And 2 bonus questions:-


  1. Should
    running
    be
    static
    ?

  2. Is
    CORE_POOL_SIZE
    redundant?


Answer

The ScheduledExecutorService has a core thread pool size of 4 but will more than one poller thread ever be created?

It depends - if you run your program long enough, it will probably create 4 threads. If you quit after running your scheduled task only once or twice, you might only see 2 or 3 threads.

Why does it matter?

One way to monitor thread creation is to provide your own ThreadFactory:

this.ses = Executors.newScheduledThreadPool(CORE_POOL_SIZE, new ThreadFactory() {

            @Override
            public Thread newThread(Runnable r) {
                System.out.println("Creating thread");
                return new Thread(r);
            }
        }); 

Should running be static?

It depends on what you want to achieve... Since you are not really it using in your example it is hard to say. You might need to make it static if you have several instances of Poller and you want them to not run concurrently for example.

Whether it is static or not, if you use it as a flag, you should make it volatile to ensure visibility.

Is CORE_POOL_SIZE redundant?

Not sure what you mean. It is a mandatory parameter so you need to provide a value. If you know for sure that no two execution will run concurrently, you could only have one thread. That will also prevent concurrent execution (so if one scheduled task needs to start but another is already running, the new one will be delayed).