com.amazon.redshift.util.SharedTimer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of redshift-jdbc42 Show documentation
Show all versions of redshift-jdbc42 Show documentation
Java JDBC 4.2 (JRE 8+) driver for Redshift database
/*
* Copyright (c) 2004, PostgreSQL Global Development Group
* See the LICENSE file in the project root for more information.
*/
package com.amazon.redshift.util;
import java.util.Timer;
import java.util.concurrent.atomic.AtomicInteger;
import com.amazon.redshift.logger.LogLevel;
import com.amazon.redshift.logger.RedshiftLogger;
public class SharedTimer {
// Incremented for each Timer created, this allows each to have a unique Timer name
private static final AtomicInteger timerCount = new AtomicInteger(0);
private static final RedshiftLogger logger = RedshiftLogger.getDriverLogger();
private volatile Timer timer = null;
private final AtomicInteger refCount = new AtomicInteger(0);
public SharedTimer() {
}
public int getRefCount() {
return refCount.get();
}
public synchronized Timer getTimer() {
if (timer == null) {
int index = timerCount.incrementAndGet();
/*
Temporarily switch contextClassLoader to the one that loaded this driver to avoid TimerThread preventing current
contextClassLoader - which may be the ClassLoader of a web application - from being GC:ed.
*/
final ClassLoader prevContextCL = Thread.currentThread().getContextClassLoader();
try {
/*
Scheduled tasks whould not need to use .getContextClassLoader, so we just reset it to null
*/
Thread.currentThread().setContextClassLoader(null);
timer = new Timer("Redshift-JDBC-SharedTimer-" + index, true);
} finally {
Thread.currentThread().setContextClassLoader(prevContextCL);
}
}
refCount.incrementAndGet();
return timer;
}
public synchronized void releaseTimer() {
int count = refCount.decrementAndGet();
if (count > 0) {
// There are outstanding references to the timer so do nothing
if(RedshiftLogger.isEnable() && logger != null)
logger.log(LogLevel.DEBUG, "Outstanding references still exist so not closing shared Timer");
} else if (count == 0) {
// This is the last usage of the Timer so cancel it so it's resources can be release.
if(RedshiftLogger.isEnable() && logger != null)
logger.log(LogLevel.DEBUG, "No outstanding references to shared Timer, will cancel and close it");
if (timer != null) {
timer.cancel();
timer = null;
}
} else {
// Should not get here under normal circumstance, probably a bug in app code.
if(RedshiftLogger.isEnable() && logger != null)
logger.log(LogLevel.INFO,
"releaseTimer() called too many times; there is probably a bug in the calling code");
refCount.set(0);
}
}
}