[ https://issues.apache.org/jira/browse/ARTEMIS-968?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15869399#comment-15869399 ]
Erich Duda commented on ARTEMIS-968: ------------------------------------ I searched how to implement ThreadPoolExecutor which would behave like ActiveMQThreadPoolExecutor on the Internet but I haven't found anything relevant. I think it's not possible to do it by extending JDK implementation of ThreadPoolExecutor, because you don't have access to internal structures and locks. I am thinking about modifying of OpenJDK implementation. What do you think? Is it good idea? Thanks! > Synchronization issue in ActiveMQThreadPoolExecutor > --------------------------------------------------- > > Key: ARTEMIS-968 > URL: https://issues.apache.org/jira/browse/ARTEMIS-968 > Project: ActiveMQ Artemis > Issue Type: Bug > Components: Broker > Affects Versions: 1.5.2, 2.0.0 > Reporter: Erich Duda > > During investigation of test failures in Artemis test suite I've noticed that > {{ActiveMQThreadPoolExecutor}} sometimes doesn't allocate new Worker for a > task even if {{maxPoolSize = 16}} and there are only 3 tasks to execute. > Instead the task is queued and it waits until some worker finishes its job. > I think the problem is in offer method. > {code} > @Override > public boolean offer(Runnable runnable) { > int poolSize = executor.getPoolSize(); > // If the are less threads than the configured maximum, then the tasks is > // only queued if there are some idle threads that can run that tasks. > // We have to add the queue size, since some tasks might just have been > queued > // but not yet taken by an idle thread. > if (poolSize < executor.getMaximumPoolSize() && (size() + > executor.getActive()) >= poolSize) > return false; > return super.offer(runnable); > } > {code} > There are 3 variables which are compared with themselves - > {{executor.getPoolSize()}}, {{size()}}, {{executor.getActive()}} - without > any synchronization. It may happen that the if condition is {{false}} just > because some variable hasn't been updated yet. > I've created reproducer \[1\] for this issue. You can run it from branch > \[2\] using following commands. > {code} > git clone https://github.com/dudaerich/activemq-artemis > cd activemq-artemis > git checkout ActiveMQThreadPoolExecutorTest > mvn test -Dtest=ActiveMQThreadPoolExecutorTest -Ptests -DfailIfNoTests=false > -Drat.ignoreErrors=true 2>&1 | tee log > {code} > \[1\] > https://github.com/dudaerich/activemq-artemis/blob/a0eb0ea9caaf22a9d031d480625a638a2e0f300d/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/util/ActiveMQThreadPoolExecutorTest.java > \[2\] > https://github.com/dudaerich/activemq-artemis/commits/ActiveMQThreadPoolExecutorTest -- This message was sent by Atlassian JIRA (v6.3.15#6346)