Changeset 14261 in josm for trunk/src/org


Ignore:
Timestamp:
2018-09-19T21:57:27+02:00 (6 years ago)
Author:
wiktorn
Message:

Use corePoolSize = maxPoolSize and unbounded queue

Remove hack with calling setCorePoolSize to spawn new threads when already
corePoolSize is running. For bigger sizes of the ThreadPool setCorePoolSize took
a long time and blocked EDT thread. Now we will have always `maximum concurren
downloads` threads running for TMS layers, but this is not a big issue, as the
thread pool is shared between imagery layers.

As long as number of threads will not reach the maximum concurrent downloads
the maximum concurrent downloads per host limit will not be enforced (first n
downloads).

See: #16734

Location:
trunk/src/org/openstreetmap/josm/data
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/cache/HostLimitQueue.java

    r12865 r14261  
    99import java.util.concurrent.LinkedBlockingDeque;
    1010import java.util.concurrent.Semaphore;
    11 import java.util.concurrent.ThreadPoolExecutor;
    1211import java.util.concurrent.TimeUnit;
    1312
     
    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
     
    4639    public HostLimitQueue(int hostLimit) {
    4740        super(); // create unbounded queue
     41        this.hostLimit = hostLimit;
     42    }
     43
     44    /**
     45     * Creates bounded queue
     46     * @param hostLimit how many parallel calls to host to allow
     47     * @param queueLimit how deep the queue should be
     48     */
     49    public HostLimitQueue(int hostLimit, int queueLimit) {
     50        super(queueLimit); // create bounded queue
    4851        this.hostLimit = hostLimit;
    4952    }
     
    117120    }
    118121
    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 
    150122    private Semaphore getSemaphore(JCSCachedTileLoaderJob<?, ?> job) {
    151123        String host;
  • trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoader.java

    r13733 r14261  
    6868     */
    6969    public static ThreadPoolExecutor getNewThreadPoolExecutor(String nameFormat, int workers) {
    70         HostLimitQueue workQueue = new HostLimitQueue(HOST_LIMIT.get().intValue());
     70        return getNewThreadPoolExecutor(nameFormat, workers, HOST_LIMIT.get().intValue());
     71    }
     72
     73    /**
     74     * @param nameFormat see {@link Utils#newThreadFactory(String, int)}
     75     * @param workers number of worker thread to keep
     76     * @param hostLimit number of concurrent downloads per host allowed
     77     * @return new ThreadPoolExecutor that will use a @see HostLimitQueue based queue
     78     */
     79    public static ThreadPoolExecutor getNewThreadPoolExecutor(String nameFormat, int workers, int hostLimit) {
    7180        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
    74                 300, // keepalive for thread
     81                workers, // keep core pool the same size as max, as we use unbounded queue so there will
     82                workers, // be never more threads than corePoolSize
     83                300, // keep alive for thread
    7584                TimeUnit.SECONDS,
    76                 workQueue,
     85                new HostLimitQueue(hostLimit),
    7786                Utils.newThreadFactory(nameFormat, Thread.NORM_PRIORITY)
    7887                );
    79         workQueue.setExecutor(executor);
    8088        return executor;
    8189    }
  • trunk/src/org/openstreetmap/josm/data/imagery/WMSCachedTileLoader.java

    r13740 r14261  
    2424
    2525    /**
    26      * Creates a TileLoader with separate WMS downloader.
     26     * Creates a TileLoader with separate WMS download thread pool.
    2727     *
    2828     * @param listener that will be notified when tile is loaded
Note: See TracChangeset for help on using the changeset viewer.