Return-Path: X-Original-To: apmail-openejb-users-archive@www.apache.org Delivered-To: apmail-openejb-users-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 4FFF2D786 for ; Tue, 21 Aug 2012 09:19:17 +0000 (UTC) Received: (qmail 31127 invoked by uid 500); 21 Aug 2012 09:19:17 -0000 Delivered-To: apmail-openejb-users-archive@openejb.apache.org Received: (qmail 30725 invoked by uid 500); 21 Aug 2012 09:19:09 -0000 Mailing-List: contact users-help@openejb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: users@openejb.apache.org Delivered-To: mailing list users@openejb.apache.org Received: (qmail 30485 invoked by uid 99); 21 Aug 2012 09:19:07 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 21 Aug 2012 09:19:07 +0000 X-ASF-Spam-Status: No, hits=-0.0 required=5.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: local policy) Received: from [194.68.48.87] (HELO xenis.dax.nu) (194.68.48.87) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 21 Aug 2012 09:18:57 +0000 Received: from kali.pri (ua-83-227-152-132.cust.bredbandsbolaget.se [83.227.152.132]) (authenticated bits=0) by xenis.dax.nu (8.14.3/8.14.1/SuSE Linux 0.8) with ESMTP id q7L9IZ6N012758 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for ; Tue, 21 Aug 2012 11:18:36 +0200 From: Bjorn Danielsson To: users@openejb.apache.org Subject: Re: Number of simultaneous @Asynchronous threads Organization: Cuspy Code AB References: <1345419028949-4656908.post@n4.nabble.com> Date: Tue, 21 Aug 2012 11:18:35 +0200 In-Reply-To: (David Blevins's message of "Mon, 20 Aug 2012 12:33:51 -0700") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.0 (xenis.dax.nu [194.68.48.87]); Tue, 21 Aug 2012 11:18:36 +0200 (CEST) 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. --=20 Bj=C3=B6rn Danielsson Cuspy Code AB David Blevins wrote: > On Aug 20, 2012, at 10:55 AM, Romain Manni-Bucau wrote: > >> that's because we use a linked blocking queue >>=20 >> maybe we should make it configurable, not sure... > > > Made it configurable. Code is basically: > > public static AsynchronousPool create(AppContext appContext) { > final Options options =3D appContext.getOptions(); > > final String id =3D appContext.getId(); > final int corePoolSize =3D options.get("AsynchronousPool.CorePool= Size", 10); > final int maximumPoolSize =3D Math.max(options.get("AsynchronousP= ool.MaximumPoolSize", 20), corePoolSize); > final Duration keepAliveTime =3D options.get("AsynchronousPool.Ke= epAliveTime", new Duration(60, TimeUnit.SECONDS)); > final BlockingQueue queue =3D options.get("AsynchronousPool.Queue= Type", QueueType.LINKED).create(options); > > return new AsynchronousPool(id, corePoolSize, maximumPoolSize, ke= epAliveTime, queue); > } > > private static enum QueueType { > ARRAY, > DELAY, > LINKED, > PRIORITY, > SYNCHRONOUS; > > public BlockingQueue create(Options options) { > switch (this) { > case ARRAY: { > return new ArrayBlockingQueue(options.get("Asynchrono= usPool.QueueSize", 100)); > } > case DELAY: { > return new DelayQueue(); > } > case LINKED: { > return new LinkedBlockingQueue(options.get("Asynchron= ousPool.QueueSize", Integer.MAX_VALUE)); > } > case PRIORITY: { > return new PriorityBlockingQueue(); > } > case SYNCHRONOUS: { > return new SynchronousQueue(options.get("Asynchronous= Pool.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); > } > } > } > }