11

I am wondering what is the difference between these two methods of Executors class? I have a web application where I'm checking some data every 100 ms so that's why I'm using this scheduler with scheduleWithFixedDelay method. I want to know which method should I use in this case (newScheduledThreadPool or newSingleThreadScheduledExecutor)? I also have one more question - in VisualVM where I monitor my Glassfish server I noticed that I have some threads in PARK state - for example:

java.lang.Thread.State: WAITING
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for <3cb9965d> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Is it possible that these threads are connected with scheduler because I don't have any idea what else would create them? These threads are never destroyed, so I am afraid that this could cause some troubles. Here is a screenshot (new Thread-35 will be created in 15minutes and so on...):

enter image description here

user4341206
  • 647
  • 1
  • 7
  • 26
  • 2
    A thread pool is a pool/group of threads that have a pre-configured number of threads (to start with). This is useful if you have a work-intensive scenario where each thread in the pool might work for a longer time and you want the work to be done sooner, so you create a pool of threads. A single thread - as the name implies, is just one thread executing over and over again. Depending on the nature of work and the complexity of the task, you choose between a single or pool of threads. – Praba May 04 '15 at 11:24

3 Answers3

8

As documentation states:

Unlike the otherwise equivalent newScheduledThreadPool(1) the returned executor is guaranteed not to be reconfigurable to use additional threads.

So when using newScheduledThreadPool(1)you will be able to add more threads later.

Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
  • Yes, I read this before. So there is just difference in adding more threads later? What about this statement (from documentation fornewSingleThreadExecutor ): "(Note however that if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.)" - do this also apply for newScheduledThreadPool(1) or not? – user4341206 May 04 '15 at 11:32
  • 1
    Yes, it's also apply. – Tagir Valeev May 04 '15 at 11:44
  • 1
    The pragmatic difference is that `newScheduledThreadPool(N)` with `N` > 1, will keep a number of threads in an idle state. The scheduled tasks can run in different threads, but they follow the `happen-before` model, which in this case basically means, that no two scheduled tasks will ever run in parallel (tasks scheduled for exactly the same execution time are enabled in first-in-first-out (FIFO) order of submission). If the current thread dies, a new one can be simply taken from the pool which may be faster. Executor will maintain the number of thread to be `N`. – Marcin Czenko Nov 16 '15 at 13:45
6

newSingleThreadScheduledExecuto() is wrapped by a delegate, as you can see in Executors.java:

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

Differences (from javadoc):

if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.

Unlike the otherwise equivalent {@code newScheduledThreadPool(1)} the returned executor is guaranteed not to be reconfigurable to use additional threads.

reply to your comment:

do this also apply for newScheduledThreadPool(1) or not?

no, you need to take care of thread failure yourself.

As for Unsafe.park(), see this.

Community
  • 1
  • 1
wings
  • 791
  • 6
  • 21
  • OK, thank you. So for my case I think it's fine to use newSingleThreadScheduledExecutor(). Is it possible that I have these PARK state threads (see screenshot above) because of using newSingleThreadScheduledExecutor()? EDIT: I saw topic about Unsafe.park() already but I can't figure it out what is causing it, so I am wondering if someone knows if there were any problems connected with scheduler... – user4341206 May 04 '15 at 11:43
  • @user4341206 Sorry, I'm no sure. But it seems likely. Because the single thread will be kept in the thread pool even when idle. – wings May 04 '15 at 11:49
  • When the old thread does not finish in time, a new task will still be added to the pool. – wings May 04 '15 at 12:12
  • 1
    The answer to the question above "do this also apply for newScheduledThreadPool(1) or not?" is YES. The `1` passed to the constructor of the `ScheduledThreadPoolExecutor` is `corePoolSize`. Unless you set it to `0`, which is not recommended, the `ScheduledThreadPoolExecutor` will re-create the threads if the previously executing thread died from an exception and one is need. The **only** difference between `newSingleThreadScheduledExecutor()` and `newScheduledThreadPool(1)` is that in the first case the executor is guaranteed not to be reconfigurable to use additional threads. – Marcin Czenko Nov 16 '15 at 13:38
  • The difference is the DelegatedScheduledExecutorService exposes only `schedule` and `invoke` related methods. All other configuration methods can not be invoked from it. – Jun Mar 22 '19 at 02:50
1

As pointed out by wings and tagir the differences is in "how to manage failure".

About Thread your thread is in Wait status; park is not a status but is a method to put the Thread in wait status; see also

How to detect thread being blocked by IO?

However, let me suggest a different way to implement a scheduled thread on Java EE; you should take a look at EJB's TimerService

@Singleton
public class TimerSessionBean {
    @Resource
    TimerService timerService;   

    public void setTimer(long intervalDuration) {
        Timer timer = timerService.createTimer(intervalDuration, 
                "Created new programmatic timer");
    }

    @Timeout
    public void lookForData(Timer timer) {
        //this.setLastProgrammaticTimeout(new Date());
        ....
    }

    //OR
    @Schedule(minute = "*/1", hour = "*")
    public void runEveryMinute() {
      ...
    }

   }
Community
  • 1
  • 1
venergiac
  • 7,469
  • 2
  • 48
  • 70