View Javadoc
1   /*
2    * junixsocket
3    *
4    * Copyright 2009-2026 Christian Kohlschütter
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.newsclub.net.unix.pool;
19  
20  import java.io.Closeable;
21  
22  import org.eclipse.jdt.annotation.NonNull;
23  import org.newsclub.net.unix.ThreadUtil;
24  
25  /**
26   * A pool of objects.
27   *
28   * @param <O> The object type.
29   * @author Christian Kohlschütter
30   */
31  @SuppressWarnings("PMD.ImplicitFunctionalInterface")
32  public interface ObjectPool<O> {
33  
34    /**
35     * Creates a new {@link ObjectPool} that is used within a single thread; this may or may not be
36     * implemented using {@link ThreadLocal}, however the behavior should be comparable.
37     *
38     * @param <O> The object type.
39     * @param supplier The object supplier.
40     * @param sanitizer The object sanitizer.
41     * @return The object pool.
42     */
43    static <O> ObjectPool<O> newThreadLocalPool(ObjectSupplier<@NonNull O> supplier,
44        ObjectSanitizer<@NonNull O> sanitizer) {
45      if (ThreadUtil.isVirtualThreadSupported()) {
46        return new VirtualAwareThreadLocalObjectPool<>(supplier, sanitizer);
47      } else {
48        return new ThreadLocalObjectPool<>(supplier, sanitizer);
49      }
50    }
51  
52    /**
53     * Returns a {@link Lease} that is not backed by any object pool.
54     *
55     * @param <O> The object type.
56     * @param obj The object.
57     * @return The lease; closing/discarding has no effect.
58     */
59    static <O> Lease<O> unpooledLease(O obj) {
60      return new Lease<O>() {
61  
62        @Override
63        public O get() {
64          return obj;
65        }
66  
67        @Override
68        public void close() {
69        }
70  
71        @Override
72        public void discard() {
73        }
74      };
75    }
76  
77    /**
78     * Takes an exclusive lease of an object from the pool. If no existing object is available from
79     * the pool, a new one may be provided.
80     *
81     * @return The object.
82     */
83    Lease<O> take();
84  
85    /**
86     * Supplies a leased object.
87     *
88     * @param <T> The object type.
89     */
90    @FunctionalInterface
91    interface ObjectSupplier<T> {
92  
93      /**
94       * Gets a result.
95       *
96       * @return a result
97       */
98      T get();
99    }
100 
101   /**
102    * Sanitizes a previously leased object so it can be reused by the pool.
103    *
104    * @param <T> The object type.
105    */
106   @FunctionalInterface
107   interface ObjectSanitizer<T> {
108     /**
109      * Sanitizes a previously leased object so it can be reused by the pool; if the object should
110      * not be reused, {@code false} is returned.
111      *
112      * @param obj The object to sanitize.
113      * @return {@code true} if sanitization was successful, {@code false} if the object should not
114      *         be reused.
115      */
116     boolean sanitize(T obj);
117   }
118 
119   /**
120    * A lease for an object (obtained via {@link #get()}); working with the object is only permitted
121    * before {@link #close()}.
122    *
123    * @param <O> The object type.
124    */
125   interface Lease<O> extends Closeable {
126     /**
127      * Returns the leased object, potentially {@code null} when discarded/closed.
128      *
129      * @return The object, or {@code null}.
130      */
131     O get();
132 
133     /**
134      * Terminates the validity of this lease. Unless discarded via {@link #discard()}, the object
135      * may end up back in the object pool it was leased from; however that is decided by the pool.
136      */
137     @Override
138     void close();
139 
140     /**
141      * Marks the leased object as discarded, potentially preventing it from being reused in the
142      * object pool.
143      */
144     void discard();
145   }
146 }