/** * $Id: ReferenceResource.java 1831 2013-05-16 01:39:51Z shijia.wxr $ */ package com.alibaba.rocketmq.store; import java.util.concurrent.atomic.AtomicLong; /** * ���ü������࣬������C++����ָ��ʵ�� * * @author vintage.wang@gmail.com shijia.wxr@taobao.com */ public abstract class ReferenceResource { protected final AtomicLong refCount = new AtomicLong(1); protected volatile boolean available = true; protected volatile boolean cleanupOver = false; private volatile long firstShutdownTimestamp = 0; /** * ��Դ�Ƿ���HOLDס */ public synchronized boolean hold() { if (this.isAvailable()) { if (this.refCount.getAndIncrement() > 0) { return true; } else { this.refCount.getAndDecrement(); } } return false; } /** * �ͷ���Դ */ public void release() { long value = this.refCount.decrementAndGet(); if (value > 0) return; synchronized (this) { // cleanup�ڲ�Ҫ���Ƿ�clean������ this.cleanupOver = this.cleanup(value); } } /** * ��ֹ��Դ������ shutdown��������ö�Σ�������ɹ����̵߳��� */ public void shutdown(final long intervalForcibly) { if (this.available) { this.available = false; this.firstShutdownTimestamp = System.currentTimeMillis(); this.release(); } // ǿ��shutdown else if (this.getRefCount() > 0) { if ((System.currentTimeMillis() - this.firstShutdownTimestamp) >= intervalForcibly) { this.refCount.set(-1000 - this.getRefCount()); this.release(); } } } /** * ��Դ�Ƿ���ã����Ƿ�ɱ�HOLD */ public boolean isAvailable() { return this.available; } /** * ��Դ�Ƿ�������� */ public boolean isCleanupOver() { return this.refCount.get() <= 0 && this.cleanupOver; } public long getRefCount() { return this.refCount.get(); } public abstract boolean cleanup(final long currentRef); }