The Crowd is Irrelevant

The NBL just played a grand final series without a crowd, the athletes played their hearts out.. “The Crowd is Irrelevant” is published by Jack Fleming.

Smartphone

独家优惠奖金 100% 高达 1 BTC + 180 免费旋转




jun 16 a

public interface ObjectFactory<T> {

void destroy(T t);

boolean validate(T t);

}

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

private static final Logger logger = Logger.getLogger(ObjectPool.class.getCanonicalName());

private final PoolConfig config;
private final ObjectFactory<T> factory;
private final ObjectPoolPartition<T>[] partitions;
private Scavenger scavenger;
private volatile boolean shuttingDown;

public ObjectPool(PoolConfig poolConfig, ObjectFactory<T> objectFactory) {
this.config = poolConfig;
this.factory = objectFactory;
this.partitions = new ObjectPoolPartition[config.getPartitionSize()];
for (int i = 0; i < config.getPartitionSize(); i++) {
partitions[i] = new ObjectPoolPartition<>(this, i, config, objectFactory, createBlockingQueue(poolConfig));
}
if (config.getScavengeIntervalMilliseconds() > 0) {
this.scavenger = new Scavenger();
this.scavenger.start();
}
}

protected BlockingQueue<Poolable<T>> createBlockingQueue(PoolConfig poolConfig) {
return new ArrayBlockingQueue<>(poolConfig.getMaxSize());
}

private Poolable<T> waitWhenSubPoolIsFull(boolean noTimeout, ObjectPoolPartition<T> subPool) {
Poolable<T> freeObject;
try {
if (noTimeout) {
freeObject = subPool.getObjectQueue().take();
} else {
freeObject = subPool.getObjectQueue().poll(config.getMaxWaitMilliseconds(), TimeUnit.MILLISECONDS);
if (freeObject == null) {
throw new PoolExhaustedException();
}
}
} catch (InterruptedException e) {
throw new RuntimeException(e); // will never happen
}
return freeObject;
}

public int getSize() {
int size = 0;
for (ObjectPoolPartition<T> subPool : partitions) {
size += subPool.getTotalCount();
}
return size;
}

public synchronized int shutdown() throws InterruptedException {
shuttingDown = true;
int removed = 0;
if (scavenger != null) {
scavenger.interrupt();
scavenger.join();
}
for (ObjectPoolPartition<T> partition : partitions) {
removed += partition.shutdown();
}
return removed;
}

private class Scavenger extends Thread {

}
}

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadLocalRandom;
import java.util.logging.Level;
import java.util.logging.Logger;

private static final Logger logger = Logger.getLogger(ObjectPoolPartition.class.getName());

private final ObjectPool<T> pool;
private final PoolConfig config;
private final int partition;
private final BlockingQueue<Poolable<T>> objectQueue;
private final ObjectFactory<T> objectFactory;
private int totalCount;

public ObjectPoolPartition(ObjectPool<T> pool, int partition, PoolConfig config,
ObjectFactory<T> objectFactory, BlockingQueue<Poolable<T>> queue) {
this.pool = pool;
this.config = config;
this.objectFactory = objectFactory;
this.partition = partition;
this.objectQueue = queue;
for (int i = 0; i < config.getMinSize(); i++) {
objectQueue.add(new Poolable<>(objectFactory.create(), pool, partition));
}
totalCount = config.getMinSize();
}

public BlockingQueue<Poolable<T>> getObjectQueue() {
return objectQueue;
}

public synchronized boolean decreaseObject(Poolable<T> obj) {
objectFactory.destroy(obj.getObject());
totalCount — ;
return true;
}

public synchronized int getTotalCount() {
return totalCount;
}

// set the scavenge interval carefully
public synchronized void scavenge() throws InterruptedException {
int delta = this.totalCount — config.getMinSize();
if (delta <= 0) return;
int removed = 0;
long now = System.currentTimeMillis();
Poolable<T> obj;
while (delta → 0 && (obj = objectQueue.poll()) != null) {
// performance trade off: delta always decrease even if the queue is empty,
// so it could take several intervals to shrink the pool to the configured min value.
if (logger.isLoggable(Level.FINE))
logger.fine(“obj=” + obj + “, now-last=” + (now — obj.getLastAccessTs()) + “, max idle=” +
config.getMaxIdleMilliseconds());
if (now — obj.getLastAccessTs() > config.getMaxIdleMilliseconds() &&
ThreadLocalRandom.current().nextDouble(1) < config.getScavengeRatio()) {
decreaseObject(obj); // shrink the pool size if the object reaches max idle time
removed++;
} else {
objectQueue.put(obj); //put it back
}
}
if (removed > 0 && logger.isLoggable(Level.FINE)) logger.fine(removed + “ objects were scavenged.”);
}

public synchronized int shutdown() {
int removed = 0;
long startTs = System.currentTimeMillis();
while (this.totalCount > 0 && System.currentTimeMillis() — startTs < config.getShutdownWaitMilliseconds()) {
Poolable<T> obj = objectQueue.poll();
if (obj != null) {
decreaseObject(obj);
removed++;
}
}
return removed;
}
}

public class PoolConfig {

private int maxWaitMilliseconds = 5000; // when pool is full, wait at most 5 seconds, then throw an exception
private int maxIdleMilliseconds = 300000; // objects idle for 5 minutes will be destroyed to shrink the pool size
private int minSize = 5;
private int maxSize = 20;
private int partitionSize = 4;
private int scavengeIntervalMilliseconds = 1000 * 60 * 2;
private double scavengeRatio = 0.5; // avoid cleaning up all connections in the pool at the same time
private int shutdownWaitMilliseconds = 1000 * 30;

public int getMaxWaitMilliseconds() {
return maxWaitMilliseconds;
}

public int getMinSize() {
return minSize;
}

public PoolConfig setMinSize(int minSize) {
this.minSize = minSize;
return this;
}

public int getMaxSize() {
return maxSize;
}

public PoolConfig setMaxSize(int maxSize) {
this.maxSize = maxSize;
return this;
}

public int getMaxIdleMilliseconds() {
return maxIdleMilliseconds;
}

public PoolConfig setMaxIdleMilliseconds(int maxIdleMilliseconds) {
this.maxIdleMilliseconds = maxIdleMilliseconds;
return this;
}

public int getPartitionSize() {
return partitionSize;
}

public PoolConfig setPartitionSize(int partitionSize) {
this.partitionSize = partitionSize;
return this;
}

public int getScavengeIntervalMilliseconds() {
return scavengeIntervalMilliseconds;
}

public double getScavengeRatio() {
return scavengeRatio;
}

public int getShutdownWaitMilliseconds() {
return shutdownWaitMilliseconds;
}

public class PoolExhaustedException extends RuntimeException {

public PoolExhaustedException() {
super(“Cannot get an object, the pool is exhausted.”);
}
}

public class PoolInvalidObjectException extends RuntimeException {
public PoolInvalidObjectException() {
super(“Cannot find an object that can be validated by ObjectFactory.validate()”);
}
}

public class Poolable<T> implements AutoCloseable {

private final T object;
private ObjectPool<T> pool;
private final int partition;
private long lastAccessTs;

public Poolable(T t, ObjectPool<T> pool, int partition) {
this.object = t;
this.pool = pool;
this.partition = partition;
this.lastAccessTs = System.currentTimeMillis();
}

public T getObject() {
return object;
}

public ObjectPool<T> getPool() {
return pool;
}

public int getPartition() {
return partition;
}

public void returnObject() {
pool.returnObject(this);
}

public long getLastAccessTs() {
return lastAccessTs;
}

public void setLastAccessTs(long lastAccessTs) {
this.lastAccessTs = lastAccessTs;
}

Add a comment

Related posts:

About Signzy

An article about how Unified Data Protection Regulation in the country will affect state, national and international banks in the US.

Why is acceleration a constant in the universe?

Our Universe is Dynamic: Everything is moving in every place in space. Nothing is still anywhere in the Cosmos. The Universe needs to move, the acceleration occurs in small torques or momentums that…

The Ultimate Guide to hiring a professional Kitchen Plumbing and Annual Boiler Service

Kitchen plumbing includes water supply lines and in many cases gas supply lines. The visible part of the plumbing in the sink is almost always located directly below the sink, inside the bottom sink…