ConcurrentLinkedQueue Object Pool implementation

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
3
down vote

favorite
1












I have implemented this simple unbounded ObjectPool based on a ConcurrentLinkedQueue of WeakReferences. I have a thread-unsafe object that is pretty expensive to create, and most of the time it will be used from one or two concurrent threads, but it should support any number of threads concurrently. The object has also a large memory footprint, so keeping them in memory indefintely isn't an option.



The pool usage is simple:



ObjectPool<ExpensiveObject> pool = new ObjectPool(ExpensiveObject::new);

try (ObjectPool<ExpensiveObject>.Ref ref = pool.acquire())
ExpensiveObject obj = ref.obj();
//...



I've been using this implementation in production for some time now, but I have never seen any other like that. Most ObjectPool implementations I see are way more complex. I wonder if I'm missing something.





import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.function.Supplier;

public class ObjectPool<T>
private final ConcurrentLinkedQueue<Ref> queue = new ConcurrentLinkedQueue<>();
private final Supplier<T> factory;
private final int maxRetries;

@SuppressWarnings("unused", "FieldCanBeLocal")
private final List<T> strong;
//keeping a strong reference to minPoolSize elements to avoid their collection

public ObjectPool(Supplier<T> factory)
this(factory, 1, 5);


public ObjectPool(Supplier<T> factory, int minPoolSize, int maxRetries)
this.maxRetries = maxRetries;
this.factory = factory;
this.strong = initMinPool(factory, minPoolSize);


private List<T> initMinPool(Supplier<T> factory, int minPoolSize)
List<T> strong = new ArrayList<>();
for (int i = 0; i < minPoolSize; i++)
try (Ref ref = new Ref(factory.get()))
strong.add(ref.obj());


return strong;


public Ref acquire()
Ref ref = null;

for (int i = 0; i < maxRetries; i++)
ref = queue.poll();

//either empty pool or valid deref'd object
if (ref == null

if (ref == null)
ref = new Ref(factory.get());

return ref;


public class Ref implements Closeable
private final WeakReference<T> ref;
private T obj;

private Ref(T obj)
this.ref = new WeakReference<>(obj);
this.obj = obj;


private boolean materialize()
this.obj = ref.get();
return this.obj != null;


public T obj()
return obj;


@Override
public void close()
if (obj == null) return;
obj = null;
queue.offer(this);









share|improve this question





















  • Elegant 😊 I can see why you are proud of this. IMHO a few more comments would be appropriate as this is quite complicated.
    – OldCurmudgeon
    Apr 28 at 22:24

















up vote
3
down vote

favorite
1












I have implemented this simple unbounded ObjectPool based on a ConcurrentLinkedQueue of WeakReferences. I have a thread-unsafe object that is pretty expensive to create, and most of the time it will be used from one or two concurrent threads, but it should support any number of threads concurrently. The object has also a large memory footprint, so keeping them in memory indefintely isn't an option.



The pool usage is simple:



ObjectPool<ExpensiveObject> pool = new ObjectPool(ExpensiveObject::new);

try (ObjectPool<ExpensiveObject>.Ref ref = pool.acquire())
ExpensiveObject obj = ref.obj();
//...



I've been using this implementation in production for some time now, but I have never seen any other like that. Most ObjectPool implementations I see are way more complex. I wonder if I'm missing something.





import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.function.Supplier;

public class ObjectPool<T>
private final ConcurrentLinkedQueue<Ref> queue = new ConcurrentLinkedQueue<>();
private final Supplier<T> factory;
private final int maxRetries;

@SuppressWarnings("unused", "FieldCanBeLocal")
private final List<T> strong;
//keeping a strong reference to minPoolSize elements to avoid their collection

public ObjectPool(Supplier<T> factory)
this(factory, 1, 5);


public ObjectPool(Supplier<T> factory, int minPoolSize, int maxRetries)
this.maxRetries = maxRetries;
this.factory = factory;
this.strong = initMinPool(factory, minPoolSize);


private List<T> initMinPool(Supplier<T> factory, int minPoolSize)
List<T> strong = new ArrayList<>();
for (int i = 0; i < minPoolSize; i++)
try (Ref ref = new Ref(factory.get()))
strong.add(ref.obj());


return strong;


public Ref acquire()
Ref ref = null;

for (int i = 0; i < maxRetries; i++)
ref = queue.poll();

//either empty pool or valid deref'd object
if (ref == null

if (ref == null)
ref = new Ref(factory.get());

return ref;


public class Ref implements Closeable
private final WeakReference<T> ref;
private T obj;

private Ref(T obj)
this.ref = new WeakReference<>(obj);
this.obj = obj;


private boolean materialize()
this.obj = ref.get();
return this.obj != null;


public T obj()
return obj;


@Override
public void close()
if (obj == null) return;
obj = null;
queue.offer(this);









share|improve this question





















  • Elegant 😊 I can see why you are proud of this. IMHO a few more comments would be appropriate as this is quite complicated.
    – OldCurmudgeon
    Apr 28 at 22:24













up vote
3
down vote

favorite
1









up vote
3
down vote

favorite
1






1





I have implemented this simple unbounded ObjectPool based on a ConcurrentLinkedQueue of WeakReferences. I have a thread-unsafe object that is pretty expensive to create, and most of the time it will be used from one or two concurrent threads, but it should support any number of threads concurrently. The object has also a large memory footprint, so keeping them in memory indefintely isn't an option.



The pool usage is simple:



ObjectPool<ExpensiveObject> pool = new ObjectPool(ExpensiveObject::new);

try (ObjectPool<ExpensiveObject>.Ref ref = pool.acquire())
ExpensiveObject obj = ref.obj();
//...



I've been using this implementation in production for some time now, but I have never seen any other like that. Most ObjectPool implementations I see are way more complex. I wonder if I'm missing something.





import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.function.Supplier;

public class ObjectPool<T>
private final ConcurrentLinkedQueue<Ref> queue = new ConcurrentLinkedQueue<>();
private final Supplier<T> factory;
private final int maxRetries;

@SuppressWarnings("unused", "FieldCanBeLocal")
private final List<T> strong;
//keeping a strong reference to minPoolSize elements to avoid their collection

public ObjectPool(Supplier<T> factory)
this(factory, 1, 5);


public ObjectPool(Supplier<T> factory, int minPoolSize, int maxRetries)
this.maxRetries = maxRetries;
this.factory = factory;
this.strong = initMinPool(factory, minPoolSize);


private List<T> initMinPool(Supplier<T> factory, int minPoolSize)
List<T> strong = new ArrayList<>();
for (int i = 0; i < minPoolSize; i++)
try (Ref ref = new Ref(factory.get()))
strong.add(ref.obj());


return strong;


public Ref acquire()
Ref ref = null;

for (int i = 0; i < maxRetries; i++)
ref = queue.poll();

//either empty pool or valid deref'd object
if (ref == null

if (ref == null)
ref = new Ref(factory.get());

return ref;


public class Ref implements Closeable
private final WeakReference<T> ref;
private T obj;

private Ref(T obj)
this.ref = new WeakReference<>(obj);
this.obj = obj;


private boolean materialize()
this.obj = ref.get();
return this.obj != null;


public T obj()
return obj;


@Override
public void close()
if (obj == null) return;
obj = null;
queue.offer(this);









share|improve this question













I have implemented this simple unbounded ObjectPool based on a ConcurrentLinkedQueue of WeakReferences. I have a thread-unsafe object that is pretty expensive to create, and most of the time it will be used from one or two concurrent threads, but it should support any number of threads concurrently. The object has also a large memory footprint, so keeping them in memory indefintely isn't an option.



The pool usage is simple:



ObjectPool<ExpensiveObject> pool = new ObjectPool(ExpensiveObject::new);

try (ObjectPool<ExpensiveObject>.Ref ref = pool.acquire())
ExpensiveObject obj = ref.obj();
//...



I've been using this implementation in production for some time now, but I have never seen any other like that. Most ObjectPool implementations I see are way more complex. I wonder if I'm missing something.





import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.function.Supplier;

public class ObjectPool<T>
private final ConcurrentLinkedQueue<Ref> queue = new ConcurrentLinkedQueue<>();
private final Supplier<T> factory;
private final int maxRetries;

@SuppressWarnings("unused", "FieldCanBeLocal")
private final List<T> strong;
//keeping a strong reference to minPoolSize elements to avoid their collection

public ObjectPool(Supplier<T> factory)
this(factory, 1, 5);


public ObjectPool(Supplier<T> factory, int minPoolSize, int maxRetries)
this.maxRetries = maxRetries;
this.factory = factory;
this.strong = initMinPool(factory, minPoolSize);


private List<T> initMinPool(Supplier<T> factory, int minPoolSize)
List<T> strong = new ArrayList<>();
for (int i = 0; i < minPoolSize; i++)
try (Ref ref = new Ref(factory.get()))
strong.add(ref.obj());


return strong;


public Ref acquire()
Ref ref = null;

for (int i = 0; i < maxRetries; i++)
ref = queue.poll();

//either empty pool or valid deref'd object
if (ref == null

if (ref == null)
ref = new Ref(factory.get());

return ref;


public class Ref implements Closeable
private final WeakReference<T> ref;
private T obj;

private Ref(T obj)
this.ref = new WeakReference<>(obj);
this.obj = obj;


private boolean materialize()
this.obj = ref.get();
return this.obj != null;


public T obj()
return obj;


@Override
public void close()
if (obj == null) return;
obj = null;
queue.offer(this);











share|improve this question












share|improve this question




share|improve this question








edited Apr 27 at 14:43
























asked Apr 27 at 14:35









Juan Lopes

1686




1686











  • Elegant 😊 I can see why you are proud of this. IMHO a few more comments would be appropriate as this is quite complicated.
    – OldCurmudgeon
    Apr 28 at 22:24

















  • Elegant 😊 I can see why you are proud of this. IMHO a few more comments would be appropriate as this is quite complicated.
    – OldCurmudgeon
    Apr 28 at 22:24
















Elegant 😊 I can see why you are proud of this. IMHO a few more comments would be appropriate as this is quite complicated.
– OldCurmudgeon
Apr 28 at 22:24





Elegant 😊 I can see why you are proud of this. IMHO a few more comments would be appropriate as this is quite complicated.
– OldCurmudgeon
Apr 28 at 22:24
















active

oldest

votes











Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f193084%2fconcurrentlinkedqueue-object-pool-implementation%23new-answer', 'question_page');

);

Post as a guest



































active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes










 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f193084%2fconcurrentlinkedqueue-object-pool-implementation%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Greedy Best First Search implementation in Rust

Function to Return a JSON Like Objects Using VBA Collections and Arrays

C++11 CLH Lock Implementation