Skip to content

Instantly share code, notes, and snippets.

@isopov
Created September 22, 2011 10:15
Show Gist options
  • Save isopov/1234475 to your computer and use it in GitHub Desktop.
Save isopov/1234475 to your computer and use it in GitHub Desktop.
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
public class CacheBuilderTest {
private static final int NUM_TASKS = 1000;
private static final int NUM_EXECUTORS = 20;
private static final long EXPIRATION_TIME = 10L;
public static void main(String[] args) {
//Solution with expiration using a thread executor
{
final Map<String, ScheduledFuture<String>> cacheNames = new ConcurrentHashMap<String, ScheduledFuture<String>>();
ScheduledExecutorService removeExpiredService = Executors.newSingleThreadScheduledExecutor();
ExecutorService exService = Executors.newFixedThreadPool(NUM_EXECUTORS);
List<MapTask> tasks = new ArrayList<MapTask>(NUM_TASKS);
for (int i = 0; i < NUM_TASKS; i++) {
tasks.add(new MapTask(String.valueOf(i % NUM_EXECUTORS), cacheNames, removeExpiredService));
}
List<Future<?>> futures = new ArrayList<Future<?>>(NUM_TASKS);
for (MapTask task : tasks) {
futures.add(exService.submit(task));
}
for (Future<?> future : futures) {
while (!future.isDone()) {
//wait
}
}
exService.shutdown();
removeExpiredService.shutdown();
}
//Solution with CacheBuilder
{
Cache<String, String> cache = CacheBuilder.newBuilder()
.expireAfterWrite(EXPIRATION_TIME, TimeUnit.MILLISECONDS)
.build(new CacheLoader<String, String>() {
@Override
public String load(String key) throws Exception {
return UUID.randomUUID().toString();
}
});
ExecutorService exService = Executors.newFixedThreadPool(NUM_EXECUTORS);
List<CacheTask> tasks = new ArrayList<CacheTask>(NUM_TASKS);
for (int i = 0; i < NUM_TASKS; i++) {
tasks.add(new CacheTask(String.valueOf(i % NUM_EXECUTORS), cache));
}
List<Future<?>> futures = new ArrayList<Future<?>>(NUM_TASKS);
for (CacheTask task : tasks) {
futures.add(exService.submit(task));
}
for (Future<?> future : futures) {
while (!future.isDone()) {
//wait
}
}
exService.shutdown();
}
}
private static class MapTask implements Runnable {
private final String cacheKey;
private final Map<String, ScheduledFuture<String>> cacheNames;
private final ScheduledExecutorService removeExpiredService;
public MapTask(String cacheKey, Map<String, ScheduledFuture<String>> cacheNames,
ScheduledExecutorService removeExpiredService) {
this.cacheKey = cacheKey;
this.cacheNames = cacheNames;
this.removeExpiredService = removeExpiredService;
}
public void run() {
while (cacheNames.containsKey(cacheKey)) {
//wait
}
cacheNames.put(cacheKey, removeExpiredService.schedule(new Callable<String>() {
public String call() throws Exception {
ScheduledFuture<String> remove = cacheNames.remove(cacheKey);
if (remove == null) {
throw new RuntimeException();
}
return null;
}
}, EXPIRATION_TIME, TimeUnit.MILLISECONDS));
UUID.randomUUID().toString();
}
}
private static class CacheTask implements Runnable {
private final String cacheKey;
private final Cache<String, String> cache;
public CacheTask(String cacheKey, Cache<String, String> cache) {
this.cacheKey = cacheKey;
this.cache = cache;
}
public void run() {
ConcurrentMap<String, String> asMap = cache.asMap();
while (asMap.containsKey(cacheKey)) {
//wait
}
try {
cache.get(cacheKey);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment