Ticket #16734: josm-corepoolsize.patch

File josm-corepoolsize.patch, 6.6 KB (added by wiktorn, 8 years ago)
  • src/org/openstreetmap/josm/data/cache/HostLimitQueue.java

    commit 92b0ab2fbc7d40e53681d489fca98419a3547f56
    Author: Wiktor Niesiobędzki <github@vink.pl>
    Date:   Fri Sep 14 23:39:03 2018 +0200
    
        Remove setCorePoolSize hack and instead use
        ThreadPool.DiscardOldestPolicy
    
    diff --git src/org/openstreetmap/josm/data/cache/HostLimitQueue.java src/org/openstreetmap/josm/data/cache/HostLimitQueue.java
    index 9f38c1d7b..aa4a397b3 100644
    import java.util.Map;  
    88import java.util.concurrent.ConcurrentHashMap;
    99import java.util.concurrent.LinkedBlockingDeque;
    1010import java.util.concurrent.Semaphore;
    11 import java.util.concurrent.ThreadPoolExecutor;
    1211import java.util.concurrent.TimeUnit;
    1312
    1413import org.openstreetmap.josm.tools.Logging;
    public class HostLimitQueue extends LinkedBlockingDeque<Runnable> {  
    3332    private final Map<String, Semaphore> hostSemaphores = new ConcurrentHashMap<>();
    3433    private final int hostLimit;
    3534
    36     private ThreadPoolExecutor executor;
    37 
    38     private int corePoolSize;
    39 
    40     private int maximumPoolSize;
    41 
    4235    /**
    4336     * Creates an unbounded queue
    4437     * @param hostLimit how many parallel calls to host to allow
    public class HostLimitQueue extends LinkedBlockingDeque<Runnable> {  
    4841        this.hostLimit = hostLimit;
    4942    }
    5043
     44    public HostLimitQueue(int hostLimit, int queueLimit) {
     45        super(queueLimit); // create unbounded queue
     46        this.hostLimit = hostLimit;
     47    }
     48
    5149    private JCSCachedTileLoaderJob<?, ?> findJob() {
    5250        for (Iterator<Runnable> it = iterator(); it.hasNext();) {
    5351            Runnable r = it.next();
    public class HostLimitQueue extends LinkedBlockingDeque<Runnable> {  
    116114        return job;
    117115    }
    118116
    119     /**
    120      * Set the executor for which this queue works. It's needed to spawn new threads.
    121      * See: http://stackoverflow.com/questions/9622599/java-threadpoolexecutor-strategy-direct-handoff-with-queue#
    122      *
    123      * @param executor executor for which this queue works
    124      */
    125     public void setExecutor(ThreadPoolExecutor executor) {
    126         this.executor = executor;
    127         this.maximumPoolSize = executor.getMaximumPoolSize();
    128         this.corePoolSize = executor.getCorePoolSize();
    129     }
    130 
    131     @Override
    132     public boolean offer(Runnable e) {
    133         if (!super.offer(e)) {
    134             return false;
    135         }
    136 
    137         if (executor != null) {
    138             // See: http://stackoverflow.com/questions/9622599/java-threadpoolexecutor-strategy-direct-handoff-with-queue#
    139             // force spawn of a thread if not reached maximum
    140             int currentPoolSize = executor.getPoolSize();
    141             if (currentPoolSize < maximumPoolSize
    142                     && currentPoolSize >= corePoolSize) {
    143                 executor.setCorePoolSize(currentPoolSize + 1);
    144                 executor.setCorePoolSize(corePoolSize);
    145             }
    146         }
    147         return true;
    148     }
    149 
    150117    private Semaphore getSemaphore(JCSCachedTileLoaderJob<?, ?> job) {
    151118        String host;
    152119        try {
  • src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoader.java

    diff --git src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoader.java src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoader.java
    index a1e566aa4..03aec0dc4 100644
    public class TMSCachedTileLoader implements TileLoader, CachedTileLoader {  
    6767     * @return new ThreadPoolExecutor that will use a @see HostLimitQueue based queue
    6868     */
    6969    public static ThreadPoolExecutor getNewThreadPoolExecutor(String nameFormat, int workers) {
    70         HostLimitQueue workQueue = new HostLimitQueue(HOST_LIMIT.get().intValue());
    7170        ThreadPoolExecutor executor = new ThreadPoolExecutor(
    72                 0, // 0 so for unused thread pools threads will eventually die, freeing also the threadpool
    73                 workers, // do not this number of threads
     71                0, // keep core pool the same size as max
     72                workers, // do not exceed this number of threads
    7473                300, // keepalive for thread
    7574                TimeUnit.SECONDS,
    76                 workQueue,
     75                new HostLimitQueue(HOST_LIMIT.get().intValue(), workers),
    7776                Utils.newThreadFactory(nameFormat, Thread.NORM_PRIORITY)
    7877                );
    79         workQueue.setExecutor(executor);
     78        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
    8079        return executor;
    8180    }
    8281
  • test/unit/org/openstreetmap/josm/data/cache/HostLimitQueueTest.java

    diff --git test/unit/org/openstreetmap/josm/data/cache/HostLimitQueueTest.java test/unit/org/openstreetmap/josm/data/cache/HostLimitQueueTest.java
    index 36e7cde59..f3c6615e4 100644
    public class HostLimitQueueTest {  
    3333    public JOSMTestRules test = new JOSMTestRules().preferences().timeout(20 * 1000);
    3434
    3535    private static ThreadPoolExecutor getNewThreadPoolExecutor(String nameFormat, int workers, int queueLimit) {
    36         HostLimitQueue workQueue = new HostLimitQueue(queueLimit);
    3736        ThreadPoolExecutor executor = new ThreadPoolExecutor(
    38                 0, // 0 so for unused thread pools threads will eventually die, freeing also the threadpool
    39                 workers, // do not this number of threads
     37                0, // keep core pool the same size as max
     38                workers, // do not exceed this number of threads
    4039                300, // keepalive for thread
    4140                TimeUnit.SECONDS,
    42                 workQueue,
     41                new HostLimitQueue(queueLimit, workers),
    4342                Utils.newThreadFactory(nameFormat, Thread.NORM_PRIORITY)
    4443                );
    45         workQueue.setExecutor(executor);
    4644        return executor;
    4745    }
    4846
    public class HostLimitQueueTest {  
    6361        public void run() {
    6462            try {
    6563                Thread.sleep(1000);
    66             } catch (InterruptedException e) {
     64                System.out.println("downloaded: " + getUrl().toString());
     65            } catch (InterruptedException | IOException e) {
    6766                Logging.trace(e);
    6867            } finally {
    6968                this.counter.incrementAndGet();
    public class HostLimitQueueTest {  
    9897        AtomicInteger counter = new AtomicInteger(0);
    9998        long start = System.currentTimeMillis();
    10099        for (int i = 0; i < 10; i++) {
     100            System.out.println("exec: " + i);
    101101            tpe.execute(new Task(cache, new URL("http://localhost/"+i), counter));
    102102        }
    103103        tpe.shutdown();