Can you give an example when a SynchronousQueue would block
too much? In my tests it works exactly like I would expect a
bounded queue with a size of zero to behave. The thread pool
reaches MaximumPoolSize and then a RejectedExecutionException
is thrown. For a LinkedBlockingQueue with size 1, exactly the
same thing happens but one submission later, since one element
was queued before the thread pool started to expand.

For the array vs bounded linked queue, I can't see how there
are any practical differences for a ThreadPoolExecutor except
for how memory is used to store the Runnable pointers in the
queue.

-- 
Björn Danielsson
Cuspy Code AB


Romain Manni-Bucau <rmannibu...@gmail.com> wrote:
> hmm,
>
> on the jvm implementation i personnaly think it is a good implementation
> but the unbounded linkedblockingqueue case is not the one for which the
> impl was designed IMO that's why it sounds strange i think.
>
> about the conf i prefer to not switch to synchrous queue too easily since
> it can blocks too much (could be a pity for sthg asynchronous ;)).
>
> finally between array or linked case the main difference will be the array
> case is less tolerant but i agree in an application well configured it
> shouldn't make any difference.
>
> *Romain Manni-Bucau*
> *Twitter: @rmannibucau*
> *Blog: http://rmannibucau.wordpress.com*
>
>
>
>
> 2012/8/21 Bjorn Danielsson <bjorn-apa...@lists.cuspycode.com>
>
>> In my opinion this is a bit overkill, at least the options for
>> using DelayQueue and PriorityBlockingQueue. They require the
>> Runnable queue elements to implement the Delayed and Comparable
>> interfaces, respectively. I don't see how to make use of that in
>> an EJB method call.
>>
>> I looked at the Sun ThreadPoolExecutor docs and have now played
>> a little with it in a standalone program. I honestly think the
>> design is a bit bizarre. I would expect the thread pool to expand
>> to max capacity before tasks are put in the wait queue. For the
>> purpose of optimizing CPU core utilization, the number of threads
>> in the operating system run-queue is the only important number,
>> not the number of provisioned threads in a JVM thread pool.
>> But this is slightly off-topic here.
>>
>> I believe it's enough to have just one more configuration
>> property for TomEE: AsynchronousPool.QueueSize. If this is 0,
>> let the container use a SynchronousQueue. Otherwise use a
>> LinkedBlockingQueue with the specified capacity. That way it's
>> possible to have any of the three queueing strategies mentioned
>> in the ThreadPoolExecutor javadocs. I can't imagine a situation
>> where using an ArrayBlockingQueue instead of a bounded
>> LinkedBlockingQueue in TomEE really makes a big difference,
>> but I could be wrong about that.
>>
>> --
>> Björn Danielsson
>> Cuspy Code AB
>>
>>
>> David Blevins <david.blev...@gmail.com> wrote:
>> > On Aug 20, 2012, at 10:55 AM, Romain Manni-Bucau wrote:
>> >
>> >> that's because we use a linked blocking queue
>> >>
>> >> maybe we should make it configurable, not sure...
>> >
>> >
>> > Made it configurable.  Code is basically:
>> >
>> >     public static AsynchronousPool create(AppContext appContext) {
>> >         final Options options = appContext.getOptions();
>> >
>> >         final String id = appContext.getId();
>> >         final int corePoolSize =
>> options.get("AsynchronousPool.CorePoolSize", 10);
>> >         final int maximumPoolSize =
>> Math.max(options.get("AsynchronousPool.MaximumPoolSize", 20), corePoolSize);
>> >         final Duration keepAliveTime =
>> options.get("AsynchronousPool.KeepAliveTime", new Duration(60,
>> TimeUnit.SECONDS));
>> >         final BlockingQueue queue =
>> options.get("AsynchronousPool.QueueType", QueueType.LINKED).create(options);
>> >
>> >         return new AsynchronousPool(id, corePoolSize, maximumPoolSize,
>> keepAliveTime, queue);
>> >     }
>> >
>> >     private static enum QueueType {
>> >         ARRAY,
>> >         DELAY,
>> >         LINKED,
>> >         PRIORITY,
>> >         SYNCHRONOUS;
>> >
>> >         public BlockingQueue create(Options options) {
>> >             switch (this) {
>> >                 case ARRAY: {
>> >                     return new
>> ArrayBlockingQueue(options.get("AsynchronousPool.QueueSize", 100));
>> >                 }
>> >                 case DELAY: {
>> >                     return new DelayQueue();
>> >                 }
>> >                 case LINKED: {
>> >                     return new
>> LinkedBlockingQueue(options.get("AsynchronousPool.QueueSize",
>> Integer.MAX_VALUE));
>> >                 }
>> >                 case PRIORITY: {
>> >                     return new PriorityBlockingQueue();
>> >                 }
>> >                 case SYNCHRONOUS: {
>> >                     return new
>> SynchronousQueue(options.get("AsynchronousPool.QueueFair", false));
>> >                 }
>> >                 default: {
>> >                     // The Options class will throw an error if the user
>> supplies an unknown enum string
>> >                     // The only way we can reach this is if we add a new
>> QueueType element and forget to
>> >                     // implement it in the above switch statement.
>> >                     throw new IllegalArgumentException("Unknown
>> QueueType type: " + this);
>> >                 }
>> >             }
>> >         }
>> >     }
>>

Reply via email to