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:-
running
be static
? CORE_POOL_SIZE
redundant? 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).
scheduleAtFixedRate (Runnable, long initialDelay, long period, TimeUnit timeunit)
This method schedules a task to be executed periodically. The task is executed the first time after the initialDelay, and then recurringly every time the period expires.
If any execution of the given task throws an exception, the task is no longer executed. If no exceptions are thrown, the task will continue to be executed until the ScheduledExecutorService is shut down.
If a task takes longer to execute than the period between its scheduled executions, the next execution will start after the current execution finishes. The scheduled task will not be executed by more than one thread at a time.
Why do you put your executor service in Runnable
class? You should separate your ScheduledExecutorService
as Singleton rather than being variable of runnable class.
Remind this ScheduledExecutorService
is a thread container, so when you code this
this.ses = Executors.newScheduledThreadPool(CORE_POOL_SIZE);
it will create a lot of threads base on value of the size on the same time, when you put this code
this.ses.scheduleAtFixedRate(this, 0, 1, TimeUnit.SECONDS);
the ScheduledExecutorService
will randomly pick a thread which idle to run this class every 1 second until it is finish. if you put sleep
in run method that is longer than value of period time pass to scheduled thread, it wont create another thread until the 1st thread is finish. So if you want multiple thread run this Poller
on the same time, then create multiple Poller
instance and pass it to ScheduledExecutorService
CORE_POOL_SIZE
its not redundant for me, its good to be a constant which value taken from configuration file.
Should running be static? it's depends on what you need. if you intend to create multiple instance of Poller
then u shouldn't
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.