src.com.ibm.as400.resource.ResourcePool Maven / Gradle / Ivy
Show all versions of jt400-jdk8 Show documentation
///////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename: ResourcePool.java
//
// The source code contained herein is licensed under the IBM Public License
// Version 1.0, which has been approved by the Open Source Initiative.
// Copyright (C) 1997-2000 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
package com.ibm.as400.resource;
import com.ibm.as400.access.Trace;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Hashtable;
/**
The ResourcePool class represents a pool to store Resource objects
for potential lookup and reuse. For example, if a class is maintaining
several resource lists which may contain multiple objects representing
the same resource, it can use a ResourcePool object to efficiently
manage and reuse them. Such reuse may potentially reduce storage
requirements, but may also improve semantics where changes made in one
context will be reflected in other contexts.
The ResourcePool class maintains reference counts for each
registered resource. It keeps a reference to a resource as long as the
reference count is greater than zero. Therefore, it is important
to carefully manage a ResourcePool and ensure that all resources
are registered and deregistered the same number of times. Otherwise
a memory leak can result.
The caller can create and manage its own static or non-static
ResourcePool object or it can use the global static ResourcePool
defined in this class.
**/
//
// Design notes:
//
// 1. If another class declares its own ResourcePool object, I believe
// that it should be declared as transient, since it would not really
// make sense to serialize a pool.
//
class ResourcePool
{
private static final String copyright = "Copyright (C) 1997-2000 International Business Machines Corporation and others.";
// Private data.
private static final int TRACE_INCREMENT_ = 100;
private transient Hashtable resources_ = new Hashtable();
private transient Hashtable referenceCounts_ = new Hashtable();
/**
Global static resource pool.
**/
public static final ResourcePool GLOBAL_RESOURCE_POOL = new ResourcePool();
/**
Clears the pool.
**/
public void clear()
{
synchronized(this) {
resources_.clear();
referenceCounts_.clear();
}
}
/**
Deregisters a resource. If the resource is registered multiple times,
it is not removed from the pool until it is deregistered the
same number of times.
@param resource The resource.
**/
public void deregister(Resource resource)
{
if (resource == null)
throw new NullPointerException("resource");
Object resourceKey = resource.getResourceKey();
long referenceCount = -1;
boolean deregister = false;
synchronized(resources_) {
if (resources_.containsKey(resourceKey)) {
deregister = true;
referenceCount = --((long[])referenceCounts_.get(resourceKey))[0];
if (referenceCount == 0) {
resources_.remove(resourceKey);
referenceCounts_.remove(resourceKey);
if (Trace.isTraceOn()) {
int size = resources_.size();
if (size % TRACE_INCREMENT_ == 0)
Trace.log(Trace.INFORMATION, "Resource pool " + this + " contains " + size + " resources.");
}
}
}
}
}
/**
Returns a registered resource. This does not affect
the reference count.
@param resourceKey Identifies the resource.
@return The resource, or null if the identified resource
is not found.
**/
public Resource getResource(Object resourceKey)
{
if (resourceKey == null)
throw new NullPointerException("resourceKey");
return (Resource)resources_.get(resourceKey);
}
/**
Registers a resource. If a resource with the same resource ID already
exists, it is not replaced, but its reference count is increased.
@param resource The resource.
**/
public void register(Resource resource)
{
register(resource, false);
}
/**
Registers a resource. If a resource with the same resource ID already
exists, it will be optionally replaced, and its reference count is
increased.
@param resource The resource.
@param replace true if a resource with the same resource ID
is replaced, false otherwise.
**/
public void register(Resource resource, boolean replace)
{
if (resource == null)
throw new NullPointerException("resource");
Object resourceKey = resource.getResourceKey();
long referenceCount;
synchronized(this) {
if (resources_.containsKey(resourceKey)) {
if (replace)
resources_.put(resourceKey, resource);
referenceCount = ++((long[])referenceCounts_.get(resourceKey))[0];
}
else {
resources_.put(resourceKey, resource);
referenceCounts_.put(resourceKey, new long[] { 1 });
referenceCount = 1;
if (Trace.isTraceOn()) {
int size = resources_.size();
if (size % TRACE_INCREMENT_ == 0)
Trace.log(Trace.INFORMATION, "Resource pool " + this + " contains " + size + " resources.");
}
}
}
}
}