Created
February 18, 2016 12:51
-
-
Save juanplopes/03ce9a6544c5ce722c84 to your computer and use it in GitHub Desktop.
Object Pool example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package example; | |
import java.util.concurrent.ExecutorService; | |
import java.util.concurrent.Executors; | |
import java.util.concurrent.atomic.AtomicInteger; | |
public class Main { | |
public static void main(String... args) throws Exception { | |
ObjectPool<ExpensiveObject> pool = new ObjectPool<ExpensiveObject>() { | |
@Override | |
public ExpensiveObject createNew() { | |
return new ExpensiveObject(); | |
} | |
}; | |
ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2); | |
for (int i = 0; i < 1000000; i++) { | |
executor.submit(() -> pool.useObject(x -> x.doNothing() * 42)); | |
} | |
executor.shutdown(); | |
} | |
public static class ExpensiveObject { | |
private static final AtomicInteger count = new AtomicInteger(0); | |
public ExpensiveObject() { | |
try { | |
System.out.println("Thread #" + Thread.currentThread().getId() + " Creating expensive object. Total: " + count.incrementAndGet()); | |
System.out.flush(); | |
Thread.sleep(1000); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
public int doNothing() { | |
return 42; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package example; | |
import java.lang.ref.WeakReference; | |
import java.util.concurrent.ConcurrentLinkedQueue; | |
import java.util.function.Function; | |
public abstract class ObjectPool<T> { | |
private final ConcurrentLinkedQueue<WeakReference<T>> pool = new ConcurrentLinkedQueue<>(); | |
private final int maxPoolRetries; | |
public ObjectPool() { | |
this(5); | |
} | |
public ObjectPool(int maxPoolRetries) { | |
this.maxPoolRetries = maxPoolRetries; | |
} | |
public <V> V useObject(Function<T, V> callback) throws Exception { | |
T local = null; | |
WeakReference<T> ref = null; | |
for (int i = 0; i < maxPoolRetries; i++) { | |
ref = pool.poll(); | |
if (ref == null) break; //empty pool | |
local = ref.get(); | |
if (local != null) break; //valid deref'd object | |
} | |
if (local == null) { | |
local = createNew(); | |
ref = new WeakReference<T>(local); | |
} | |
try { | |
return callback.apply(local); | |
} finally { | |
pool.offer(ref); | |
} | |
} | |
public abstract T createNew(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment