https://github.com/bbottema/generic-object-pool
A flexible thread-safe generic object pool
https://github.com/bbottema/generic-object-pool
concurrency high-performance java object-pool pool
Last synced: 10 months ago
JSON representation
A flexible thread-safe generic object pool
- Host: GitHub
- URL: https://github.com/bbottema/generic-object-pool
- Owner: bbottema
- Created: 2019-06-28T13:00:02.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2024-09-15T10:04:58.000Z (over 1 year ago)
- Last Synced: 2025-04-24T03:07:15.443Z (10 months ago)
- Topics: concurrency, high-performance, java, object-pool, pool
- Language: Java
- Homepage:
- Size: 85.9 KB
- Stars: 3
- Watchers: 1
- Forks: 3
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE-2.0.txt
Awesome Lists containing this project
README
[](LICENSE-2.0.txt)
[](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.bbottema%22%20AND%20a%3A%22generic-object-pool%22)
[](https://www.javadoc.io/doc/com.github.bbottema/generic-object-pool)
[](https://www.codacy.com/app/b-bottema/generic-object-pool)
# generic-object-pool
generic-object-pool is a lightweight generic object pool, providing object lifecycle management,
metrics, claim / release mechanism and object invalidation, as well as auto initialize a core pool and
auto expiry policies.
## Setup
Maven Dependency Setup
```xml
com.github.bbottema
generic-object-pool
2.2.1
```
## Usage
#### Creating pools
```java
// basic pool with no eager loading and no expiry policy
PoolConfig poolConfig = PoolConfig.builder()
.maxPoolsize(10)
.build();
GenericObjectPool pool = new SimpleObjectPool<>(poolConfig, new MyFooAllocator());
```
```java
// more advanced pool with eager loading and auto expiry
PoolConfig poolConfig = PoolConfig.>builder()
.corePoolsize(20) // keeps 20 objects eagerly allocated at all times
.maxPoolsize(20)
// deallocate after 30 seconds, but every time an object is claimed the expiry timeout is reset
.expirationPolicy(new TimeoutSinceLastAllocationExpirationPolicy(30, TimeUnit.SECONDS))
.build();
GenericObjectPool pool = new SimpleObjectPool<>(poolConfig, new MyFooAllocator());
````
#### Claim / release API
Claiming objects from the pool (blocking):
```java
// borrow an object and block until available
PoolableObject obj = pool.claim();
````
Claiming objects from the pool (blocking until timeout):
```java
PoolableObject obj = pool.claim(key, 1, TimeUnit.SECONDS); // null if timed out
````
Releasing Objects back to the Pool:
```java
PoolableObject obj = pool.claim();
obj.release(); // make available for reuse
// or
obj.invalidate(); // remove from pool, deallocating
````
#### Shutting down a pool
```java
Future> shutdownSequence = pool.shutdown();
// wait for shutdown to complete
shutdownSequence.get();
// until timeout
shutdownSequence.get(10, TimeUnit.SECONDS);
````
#### Creating your objects
Implementing a simple Allocator to create your objects when populating the pool either eagerly or lazily.
Every method except `allocate` is optional:
```java
static class FooAllocator extends Allocator {
/**
* Initial creation and initialization.
* Called when claim comes or when pool is eagerly loading for core size.
*/
@Override
public AtomicReference allocate() {
return new Foo();
}
}
```
More comprehensive life cycle management:
```java
static class FooAllocator extends Allocator {
/**
* Initial creation and initialization.
* Called when claim comes or when pool is eagerly loading for core size.
*/
@Override
public AtomicReference allocate() {
return new Foo();
}
/**
* Uninitialize an instance which has been released back to the pool, until it is claimed again.
*/
@Override
protected void deallocateForReuse(Foo object) {
object.putAtRest();
}
/**
* Reinitialize an object so it is ready to be claimed.
*/
@Override
protected void allocateForReuse(Foo object) {
object.reinitialize();
}
/**
* Clean up an object no longer needed by the pool.
*/
@Override
protected void deallocate(Foo object) {
object.clear();
}
}
```
#### Metrics
```java
PoolMetrics metrics = pool.getPoolMetrics();
metrics.getCurrentlyClaimed(); // currently claimed by threads and not released yet
metrics.getCurrentlyWaitingCount(); // currently waiting threads that want to claim
metrics.getCorePoolsize(); // number of instances to auto allocated (eager loading)
metrics.getMaxPoolsize(); // max number of objects allowed at all times
metrics.getCurrentlyAllocated(); // available + claimed objects
metrics.getTotalAllocated(); // total number of allocations during pool's existence
metrics.getTotalClaimed(); // total number of claims during pool's existence
```
If for some reason you need to have more control over how threads are created, you can provide you own ThreadFactory:
```java
PoolConfig poolConfig = PoolConfig.>builder()
.threadFactory(new MyCustomThreadFactory())
.build();
```
#### Other Expiry strategies
You can expire objects based on age since creation or age since last allocation. For these use:
* `TimeoutSinceCreationExpirationPolicy`
* `TimeoutSinceLastAllocationExpirationPolicy`
You can also spread the expiry around in a bandwidth to avoid having everything expire at the same time, hogging system resources. for these use:
* `SpreadedTimeoutSinceCreationExpirationPolicy`
* `SpreadedTimeoutSinceLastAllocationExpirationPolicy`
You can also combine multiple expirations, by passing instances of them as a set to:
* `CombinedExpirationPolicies`
Finally, you can extend any of these or create your own from scratch by implementing:
* `ExpirationPolicy`
To aid you in creating your own expiry policy, you can calculate and store an expiry age on the poolable object:
```java
poolableObject.getExpiries().put(this, calculatedAge);
Long previouslyCalculateAge = poolableObject.getExpiries().get(this);
```
You can always extend one the abstract classes `SpreadedTimeoutExpirationPolicy` and `TimeoutExpirationPolicy`, which do this for you.