2

I am extremely confused as to why the following cast does not work:

ScheduledThreadPoolExecutor timeoutControl = (ScheduledThreadPoolExecutor) Executors.newSingleThreadScheduledExecutor();

ScheduledThreadPoolExecutor implements the ScheduledExecutorService. What's the point of this Executors call if I can't use it with an actual class.

Am I using it wrong (probably), could someone offer some guidance please?

Constantin
  • 13,382
  • 8
  • 30
  • 50

3 Answers3

4

You should only use the returned executor as a ScheduledExecutorService, rather than casting it to a ScheduledThreadPoolExecutor.

ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
Louis Wasserman
  • 172,699
  • 23
  • 307
  • 375
  • Now that I think about it, that makes sense. Thank you. – Constantin Apr 17 '12 at 22:57
  • What if I want to change a setting that's only available on the `ScheduledThreadPoolExecutor` Object (ie: `setExecuteExistingDelayedTasksAfterShutdownPolicy`)? – theyuv Jul 01 '19 at 16:44
4

The problem is that Executors.newSingleThreadScheduledExecutor(); actually doesn't return a ScheduledThreadPoolExecutor.

Source code in the Executors class:

public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
        return new DelegatedScheduledExecutorService
            (new ScheduledThreadPoolExecutor(1));
}

The Delegated... classes (there's a DelegatedExecutorService too) are just passing all the calls to the underlying executor, the ScheduledThreadPoolExecutor in this case. The comments in the code suggest that the whole point of these classes is to hide all the non-interface methods that the underlying executor might have.

In any case, it is better practice anyway to use the interface rather than the class version of the object you are working on (List and not ArrayList, ScheduledExecutorService and not ScheduledThreadPoolExecutor).

If you absolutely need functionality available in ScheduledThreadPoolExecutor and not in the ScheduledExecutorService, you could use the constructor of ScheduledThreadPoolExecutor to create an instance of it.

trutheality
  • 21,548
  • 6
  • 47
  • 65
  • Great, I see I was going about it the wrong way, thank you! After some thought, I see why. – Constantin Apr 17 '12 at 22:56
  • So, according to the souce code: `scheduled = new ScheduledThreadPoolExecutor(1)` and `scheduler = Executors.newSingleThreadScheduledExecutor()`; are equivalent? I just want to be sure (I need the ThreadPoolExecutor because I want to call one of its methods). – theyuv Jul 01 '19 at 17:07
  • @theyuv They're equivalent *except* that `newSingleThreadScheduledExecutor()` deliberately makes casting it fail. – Louis Wasserman Jul 02 '19 at 23:51
  • Why? To discourage what I'm doing (calling a method of the implementing class)? – theyuv Jul 03 '19 at 07:13
1

To simplify:

A class implementing an interface could have other methods and fields that the interface doesn't. In this case, the method returns the interface so you can't downcast this to the implementing class.

Steve Chambers
  • 31,993
  • 15
  • 129
  • 173