All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.amazon.redshift.util.SharedTimer Maven / Gradle / Ivy

There is a newer version: 2.1.0.30
Show newest version
/*
 * 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);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy