【发布时间】:2012-03-19 11:19:58
【问题描述】:
我完全被这个难住了。我有一个静态类,它管理下载的位图图像的缓存。此类由具有并发访问潜力的多个线程访问。这是实现:
public class BitmapCache {
private static final int MAX_NUMBER_BITMAPS_TO_CACHE = 30;
private static Map<String, Bitmap> bitmapCache = new HashMap<String, Bitmap>();
private static List<String> cachedBitmapUrlsOrder = new ArrayList<String>();
private BitmapCache(){}
public static synchronized void addBitmapToCache(String url, Bitmap bitmap) {
if (bitmapCache.size() >= MAX_NUMBER_BITMAPS_TO_CACHE) {
Log.i("MyApp", "Max cache size reached. Removing oldest bitmap. Size = " + bitmapCache.size());
String oldestUrl = cachedBitmapUrlsOrder.remove(0);
bitmapCache.remove(oldestUrl);
}
bitmapCache.put(url, bitmap);
cachedBitmapUrlsOrder.add(url);
}
public static int size() {
return bitmapCache.size();
}
public static Bitmap get(String url) {
return bitmapCache.get(url);
}
public synchronized static void clearCache() {
bitmapCache.clear();
}
}
我正在尝试实现滚动缓存,以便在达到最大缓存大小时(常见情况)从缓存中删除最旧的位图。运行我的应用程序会得到以下输出:
02-29 23:00:26.590: I/MyApp(10789): Max cache size reached. Removing oldest bitmap. Size = 30
02-29 23:00:26.600: I/MyApp(10789): Max cache size reached. Removing oldest bitmap. Size = 30
02-29 23:00:26.720: I/MyApp(10789): Max cache size reached. Removing oldest bitmap. Size = 30
02-29 23:00:26.790: I/MyApp(10789): Max cache size reached. Removing oldest bitmap. Size = 30
02-29 23:00:26.820: I/MyApp(10789): Max cache size reached. Removing oldest bitmap. Size = 31
02-29 23:00:26.850: I/MyApp(10789): Max cache size reached. Removing oldest bitmap. Size = 31
02-29 23:00:27.050: I/MyApp(10789): Max cache size reached. Removing oldest bitmap. Size = 32
02-29 23:00:27.070: I/MyApp(10789): Max cache size reached. Removing oldest bitmap. Size = 32
02-29 23:00:27.100: I/MyApp(10789): Max cache size reached. Removing oldest bitmap. Size = 33
02-29 23:00:27.130: I/MyApp(10789): Max cache size reached. Removing oldest bitmap. Size = 34
02-29 23:00:27.170: I/MyApp(10789): Max cache size reached. Removing oldest bitmap. Size = 35
02-29 23:00:27.210: I/MyApp(10789): Max cache size reached. Removing oldest bitmap. Size = 35
02-29 23:00:27.330: I/MyApp(10789): Max cache size reached. Removing oldest bitmap. Size = 35
02-29 23:00:27.360: I/MyApp(10789): Max cache size reached. Removing oldest bitmap. Size = 35
当缓存大小达到 30 时,代码正确地开始记录“达到最大缓存大小”并停留在那里进行几次执行。但随后它开始奇怪地增加到 35。此时它会停留在那里以增加数百个输出。我不能让它增加到超过 35。
我的实施有什么问题?鉴于addBitmapToCache 方法是同步的,我对缓存大小如何超过最大设置感到困惑。
【问题讨论】:
-
在 Jave 中,当您执行 .remove(0) 时,它会自动为您向下移动其余项目吗?
-
根据 javadoc 它确实...
-
也许值得在从地图中移除后再次记录大小以确保项目已真正被移除?
-
@assylias,很好。在缓存增加超过 30 的每一点,
bitmapCache.remove(oldestUrl)无法从缓存中删除该项目。有什么想法会发生这种情况吗? -
我认为 Graham 关于重复的观点非常好。看起来没有并发问题。
标签: android caching concurrency