From 9abc5d265baa1bc5af4e14c9c982d6b4ab4de53f Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Fri, 12 Aug 2016 13:19:00 +0200 Subject: [PATCH] introduced follow-up tasks; wait until executor has finished executing all tasks Change-Id: Ibb1ab9eb8e5dcf1b9cd4acc60bff520931f58c6a --- .../OutperformingTheGarbageCollectorTest.java | 37 +++++++++++++------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/common/test/OutperformingTheGarbageCollectorTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/common/test/OutperformingTheGarbageCollectorTest.java index efee387f13e..61c8ad3d88d 100644 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/common/test/OutperformingTheGarbageCollectorTest.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/common/test/OutperformingTheGarbageCollectorTest.java @@ -1,46 +1,59 @@ package com.sap.sailing.domain.common.test; +import java.util.HashMap; import java.util.Iterator; import java.util.Map.Entry; import java.util.NoSuchElementException; import java.util.Random; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Executor; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.logging.Level; import java.util.logging.Logger; import org.junit.Test; public class OutperformingTheGarbageCollectorTest { private static final Logger logger = Logger.getLogger(OutperformingTheGarbageCollectorTest.class.getName()); - private static final int MAX_THREADPOOL_SIZE = 300; - private static final int NUMBER_OF_OBJECTS_TO_CREATE = 50000000; + private static final int MAX_THREADPOOL_SIZE = 50; + private static final int NUMBER_OF_OBJECTS_TO_CREATE_INITIALLY = 50000000; + private static final int NUMBER_OF_FOLLOW_UP_TASKS_TO_CREATE = 1000000000; private final Random random = new Random(); - private final Executor executor = new ThreadPoolExecutor(MAX_THREADPOOL_SIZE, MAX_THREADPOOL_SIZE, 1, TimeUnit.SECONDS, new LinkedBlockingQueue()); - private final ConcurrentHashMap mapTemporarilyHoldingGarbage = new ConcurrentHashMap<>(); + private final ThreadPoolExecutor executor = new ThreadPoolExecutor(MAX_THREADPOOL_SIZE, MAX_THREADPOOL_SIZE, 1, TimeUnit.SECONDS, new LinkedBlockingQueue()); + private final ThreadLocal> mapTemporarilyHoldingGarbage = ThreadLocal.withInitial(HashMap::new); + private int numberOfFollowUpTasksCreated; @Test public void testOutperformingTheGarbageCollector() throws InterruptedException { - for (int i=0; iproduceSomeContentAndRemoveSomeOtherContent()); } - logger.info("Done with producing tasks"); + logger.info("Done with producing tasks; waiting for task queue to become empty."); + while (!executor.getQueue().isEmpty()) { + logger.info("Queue still has "+executor.getQueue().size()+" elements; still "+ + numberOfFollowUpTasksCreated+" follow-up tasks to produce; waiting..."); + Thread.sleep(1000); + } + logger.info("Task queue empty; terminating"); } private void produceSomeContentAndRemoveSomeOtherContent() { - mapTemporarilyHoldingGarbage.put(random.nextInt(Integer.MAX_VALUE), ""+random.nextDouble()); - final Iterator> i = mapTemporarilyHoldingGarbage.entrySet().iterator(); + mapTemporarilyHoldingGarbage.get().put(random.nextInt(Integer.MAX_VALUE), ""+random.nextDouble()); + final Iterator> i = mapTemporarilyHoldingGarbage.get().entrySet().iterator(); try { if (i.hasNext()) { - i.next(); - i.remove(); + final Entry entry = i.next(); + mapTemporarilyHoldingGarbage.get().remove(entry.getKey()); } else { logger.info("Strange; the collection is empty although we just added an element; welcome to concurrency..."); } } catch (NoSuchElementException e) { // ignore because some other thread may already have removed the last element, and that's OK then + logger.log(Level.INFO, "Very strange", e); + } + if (numberOfFollowUpTasksCreated < NUMBER_OF_FOLLOW_UP_TASKS_TO_CREATE) { + numberOfFollowUpTasksCreated++; + executor.execute(()->produceSomeContentAndRemoveSomeOtherContent()); } } }