1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.newsclub.net.unix.pool;
19
20 import java.util.Objects;
21 import java.util.Queue;
22 import java.util.concurrent.ConcurrentLinkedQueue;
23 import java.util.concurrent.atomic.AtomicInteger;
24
25 import org.eclipse.jdt.annotation.NonNull;
26 import org.eclipse.jdt.annotation.Nullable;
27
28
29
30
31
32
33
34 public final class ConcurrentQueueObjectPool<O> implements ObjectPool<O> {
35 private final AtomicInteger count = new AtomicInteger(0);
36 private final Queue<O> queue = new ConcurrentLinkedQueue<>();
37 private final ObjectSupplier<O> supplier;
38 private final int maxCapacity;
39 private final ObjectSanitizer<O> sanitizer;
40
41
42
43
44
45
46
47
48 public ConcurrentQueueObjectPool(ObjectSupplier<@NonNull O> supplier,
49 ObjectSanitizer<@NonNull O> sanitizer, final int maxCapacity) {
50 if (maxCapacity < 0) {
51 throw new IllegalArgumentException("maxCapacity");
52 }
53 this.supplier = Objects.requireNonNull(supplier);
54 this.sanitizer = Objects.requireNonNull(sanitizer);
55 this.maxCapacity = maxCapacity;
56 }
57
58 @Override
59 public Lease<O> take() {
60 O obj = queue.poll();
61 if (obj == null) {
62 obj = Objects.requireNonNull(supplier.get());
63 } else {
64 count.decrementAndGet();
65 }
66 return new LeaseImpl(obj);
67 }
68
69 private final class LeaseImpl implements Lease<O> {
70 private @Nullable O obj;
71
72 public LeaseImpl(O obj) {
73 this.obj = obj;
74 }
75
76 @SuppressWarnings("null")
77 @Override
78 public O get() {
79 return obj;
80 }
81
82 @Override
83 public synchronized void close() {
84 @Nullable
85 O theObject = obj;
86 obj = null;
87 if (theObject != null) {
88 if (count.get() >= maxCapacity) {
89
90 } else if (!sanitizer.sanitize(theObject)) {
91
92 } else {
93 if (queue.offer(theObject)) {
94 count.incrementAndGet();
95 }
96 }
97 }
98 }
99
100 @Override
101 public void discard() {
102 obj = null;
103 }
104 }
105 }