Changeset 8307 in josm for trunk/src/org/openstreetmap/josm/data/imagery
- Timestamp:
- 2015-05-02T00:38:57+02:00 (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java
r8286 r8307 6 6 import java.net.URL; 7 7 import java.util.Map; 8 import java.util.concurrent.ConcurrentHashMap; 8 9 import java.util.concurrent.Executor; 9 10 import java.util.concurrent.LinkedBlockingDeque; 11 import java.util.concurrent.Semaphore; 10 12 import java.util.concurrent.ThreadPoolExecutor; 11 13 import java.util.concurrent.TimeUnit; … … 20 22 import org.openstreetmap.gui.jmapviewer.interfaces.TileSource; 21 23 import org.openstreetmap.gui.jmapviewer.tilesources.AbstractTMSTileSource; 24 import org.openstreetmap.josm.Main; 22 25 import org.openstreetmap.josm.data.cache.BufferedImageCacheEntry; 23 26 import org.openstreetmap.josm.data.cache.CacheEntry; … … 42 45 */ 43 46 public static final IntegerProperty THREAD_LIMIT = new IntegerProperty("imagery.tms.tmsloader.maxjobs", 25); 47 48 /** 49 * Limit definition for per host concurrent connections 50 */ 51 public static final IntegerProperty HOST_LIMIT = new IntegerProperty("imagery.tms.tmsloader.maxjobsperhost", 6); 52 53 54 private static class LIFOQueue extends LinkedBlockingDeque<Runnable> { 55 public LIFOQueue(int capacity) { 56 super(capacity); 57 } 58 59 private final static Semaphore getSemaphore(Runnable r) { 60 if (!(r instanceof TMSCachedTileLoaderJob)) 61 return null; 62 TMSCachedTileLoaderJob cachedJob = (TMSCachedTileLoaderJob) r; 63 Semaphore limit = HOST_LIMITS.get(cachedJob.getUrl().getHost()); 64 if (limit == null) { 65 synchronized(HOST_LIMITS) { 66 limit = HOST_LIMITS.get(cachedJob.getUrl().getHost()); 67 if (limit == null) { 68 limit = new Semaphore(HOST_LIMIT.get().intValue()); 69 HOST_LIMITS.put(cachedJob.getUrl().getHost(), limit); 70 } 71 } 72 } 73 return limit; 74 } 75 76 private boolean acquireSemaphore(Runnable r) { 77 boolean ret = true; 78 Semaphore limit = getSemaphore(r); 79 if (limit != null) { 80 ret = limit.tryAcquire(); 81 if (!ret) { 82 Main.debug("rejecting job because of per host limit"); 83 } 84 } 85 return ret; 86 } 87 88 @Override 89 public boolean offer(Runnable t) { 90 return acquireSemaphore(t) && super.offerFirst(t); 91 } 92 93 private Runnable releaseSemaphore(Runnable r) { 94 Semaphore limit = getSemaphore(r); 95 if (limit != null) 96 limit.release(); 97 return r; 98 } 99 100 @Override 101 public Runnable remove() { 102 return releaseSemaphore(super.removeFirst()); 103 } 104 105 @Override 106 public Runnable poll(long timeout, TimeUnit unit) throws InterruptedException { 107 return releaseSemaphore(super.poll(timeout, unit)); 108 } 109 110 @Override 111 public Runnable take() throws InterruptedException { 112 return releaseSemaphore(super.take()); 113 } 114 } 115 116 private static Map<String, Semaphore> HOST_LIMITS = new ConcurrentHashMap<>(); 117 44 118 /** 45 119 * separate from JCS thread pool for TMS loader, so we can have different thread pools for default JCS 46 120 * and for TMS imagery 47 121 */ 48 private static ThreadPoolExecutor DOWNLOAD_JOB_DISPATCHER = new ThreadPoolExecutor( 49 THREAD_LIMIT.get().intValue(), // keep the thread number constant 50 THREAD_LIMIT.get().intValue(), // do not this number of threads 51 30, // keepalive for thread 52 TimeUnit.SECONDS, 53 // make queue of LIFO type - so recently requested tiles will be loaded first (assuming that these are which user is waiting to see) 54 new LinkedBlockingDeque<Runnable>(5) { 55 /* keep the queue size fairly small, we do not want to 56 download a lot of tiles, that user is not seeing anyway */ 57 @Override 58 public boolean offer(Runnable t) { 59 return super.offerFirst(t); 60 } 61 62 @Override 63 public Runnable remove() { 64 return super.removeFirst(); 65 } 66 } 67 ); 122 private static ThreadPoolExecutor DOWNLOAD_JOB_DISPATCHER = getThreadPoolExecutor(); 123 124 private static ThreadPoolExecutor getThreadPoolExecutor() { 125 return new ThreadPoolExecutor( 126 THREAD_LIMIT.get().intValue(), // keep the thread number constant 127 THREAD_LIMIT.get().intValue(), // do not this number of threads 128 30, // keepalive for thread 129 TimeUnit.SECONDS, 130 // make queue of LIFO type - so recently requested tiles will be loaded first (assuming that these are which user is waiting to see) 131 new LIFOQueue(5) 132 /* keep the queue size fairly small, we do not want to 133 download a lot of tiles, that user is not seeing anyway */ 134 ); 135 } 136 137 /** 138 * Reconfigures download dispatcher using current values of THREAD_LIMIT and HOST_LIMIT 139 */ 140 public static final void reconfigureDownloadDispatcher() { 141 HOST_LIMITS = new ConcurrentHashMap<>(); 142 DOWNLOAD_JOB_DISPATCHER = getThreadPoolExecutor(); 143 } 144 68 145 69 146 /**
Note:
See TracChangeset
for help on using the changeset viewer.