/*
 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.util.reentrant;

import java.lang.ref.Reference;

This ReentrantContextProvider implementation uses a ThreadLocal to hold the first ReentrantContext per thread and a ReentrantContextProviderCLQ to store child ReentrantContext instances needed during recursion. Note: this implementation may keep up to one context in memory per thread. Child contexts for recursive uses are stored in the queue using a WEAK reference by default unless specified in the 2 argument constructor.
Type parameters:
  • <K> – ReentrantContext subclass
/** * This ReentrantContextProvider implementation uses a ThreadLocal to hold * the first ReentrantContext per thread and a ReentrantContextProviderCLQ to * store child ReentrantContext instances needed during recursion. * * Note: this implementation may keep up to one context in memory per thread. * Child contexts for recursive uses are stored in the queue using a WEAK * reference by default unless specified in the 2 argument constructor. * * @param <K> ReentrantContext subclass */
public abstract class ReentrantContextProviderTL<K extends ReentrantContext> extends ReentrantContextProvider<K> { // Thread-local storage: private final ThreadLocal<Reference<K>> ctxTL = new ThreadLocal<Reference<K>>(); // ReentrantContext CLQ provider for child contexts: private final ReentrantContextProviderCLQ<K> ctxProviderCLQ;
Create a new ReentrantContext provider using the given reference type among hard, soft or weak. It uses weak reference for the child contexts.
Params:
  • refType – reference type
/** * Create a new ReentrantContext provider using the given reference type * among hard, soft or weak. * It uses weak reference for the child contexts. * * @param refType reference type */
public ReentrantContextProviderTL(final int refType) { this(refType, REF_WEAK); }
Create a new ReentrantContext provider using the given reference types among hard, soft or weak
Params:
  • refTypeTL – reference type used by ThreadLocal
  • refTypeCLQ – reference type used by ReentrantContextProviderCLQ
/** * Create a new ReentrantContext provider using the given reference types * among hard, soft or weak * * @param refTypeTL reference type used by ThreadLocal * @param refTypeCLQ reference type used by ReentrantContextProviderCLQ */
public ReentrantContextProviderTL(final int refTypeTL, final int refTypeCLQ) { super(refTypeTL); final ReentrantContextProviderTL<K> parent = this; this.ctxProviderCLQ = new ReentrantContextProviderCLQ<K>(refTypeCLQ) { @Override protected K newContext() { return parent.newContext(); } }; }
Give a ReentrantContext instance for the current thread
Returns:ReentrantContext instance
/** * Give a ReentrantContext instance for the current thread * * @return ReentrantContext instance */
@Override public final K acquire() { K ctx = null; final Reference<K> ref = ctxTL.get(); if (ref != null) { ctx = ref.get(); } if (ctx == null) { // create a new ReentrantContext if none is available ctx = newContext(); // update thread local reference: ctxTL.set(getOrCreateReference(ctx)); } // Check reentrance: if (ctx.usage == USAGE_TL_INACTIVE) { ctx.usage = USAGE_TL_IN_USE; } else { // get or create another ReentrantContext from CLQ provider: ctx = ctxProviderCLQ.acquire(); } return ctx; }
Restore the given ReentrantContext instance for reuse
Params:
  • ctx – ReentrantContext instance
/** * Restore the given ReentrantContext instance for reuse * * @param ctx ReentrantContext instance */
@Override public final void release(final K ctx) { if (ctx.usage == USAGE_TL_IN_USE) { ctx.usage = USAGE_TL_INACTIVE; } else { ctxProviderCLQ.release(ctx); } } }