3 Replies Latest reply: Jan 4, 2012 2:06 PM by jtahlborn RSS

    ThreadPoolExecutor usage

    840638
      I want to be able to set a maxPoolSize, corePoolSize and basically use an unbounded queue….such that the core threads are created and used first. If they are all busy, then I would like a thread to be created until max is reached. Once the max number of threads are busy, then queue the requests.

      It appears to me that the concurrency package creates the core threads and then queues up any requests and does not create additional threads until the queue max capacity is reached. I would prefer that the max threads be created/used first as I really want to use an unbounded queue.
      I couldn’t see a way to do this via the configuration.
      Is there a way to do this?

      In the meantime I just set the max pool and core sizes and then catch the rejection exception...at which time I add it to the queue being used by the executor.
        • 1. Re: ThreadPoolExecutor usage
          jtahlborn
          no, you can't really do this with the built-in executor. there are 2 options:

          1. use a "fixed size" pool with an unbounded queue and enable "allow core threads to timeout". this will get you most of the way there, except the min pool size is always 0.
          2. use some custom code. there are ways to achieve this behavior with not too much custom code, and i'm pretty sure you can find such code elsewhere in these forums.
          • 2. Re: ThreadPoolExecutor usage
            840638
            Yeah I really don't want the max and core sizes to be the same.
            I think I will set a queue capacity value so that it uses a LinkedBlockingQueue.
            I can catch the rejection exception which only occurs when max pools and max queue are met....When i receive the rejection,I will just
            get the queue and do a put myself....knowing this will wait until there is room.

            See any problems with this approach?

            try
            {
            taskExecutor.execute(acs)
            }
            catch (TaskRejectedException ex)
            {
            taskExecutor.getThreadPoolExecutor().getQueue().put(acs);
            }
            • 3. Re: ThreadPoolExecutor usage
              jtahlborn
              837635 wrote:
              Yeah I really don't want the max and core sizes to be the same.
              you do realize that if you enable "allow core threads to timeout" you essentially have a variable size threadpool (from 0 to max). just want to make sure you make the choice for the right reason (e.g. you really want to have a minimum which is non-zero).
              I think I will set a queue capacity value so that it uses a LinkedBlockingQueue.
              I can catch the rejection exception which only occurs when max pools and max queue are met....When i receive the rejection,I will just
              get the queue and do a put myself....knowing this will wait until there is room.

              See any problems with this approach?

              try
              {
              taskExecutor.execute(acs)
              }
              catch (TaskRejectedException ex)
              {
              taskExecutor.getThreadPoolExecutor().getQueue().put(acs);
              }
              yes, that is one technique. another is to do this but have a way to slip the object on to the queue after rejection (so a "sort of" limited queue). like i said, i'm pretty sure such code has been posted before.

              whichever way you choose to handle it, though, it's better to implement it with a custom RejectedExecutionHandler so that every user of your executor does not need to implement this logic individually.

              Edited by: jtahlborn on Jan 4, 2012 3:05 PM