1/* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25package sun.java2d; 26 27import java.lang.ref.Reference; 28 29/** 30* This ReentrantContextProvider implementation uses a ThreadLocal to hold 31 * the first ReentrantContext per thread and a ReentrantContextProviderCLQ to 32 * store child ReentrantContext instances needed during recursion. 33 * 34 * Note: this implementation may keep up to one context in memory per thread. 35 * Child contexts for recursive uses are stored in the queue using a WEAK 36 * reference by default unless specified in the 2 argument constructor. 37 * 38 * @param <K> ReentrantContext subclass 39 */ 40public abstract class ReentrantContextProviderTL<K extends ReentrantContext> 41 extends ReentrantContextProvider<K> 42{ 43 // Thread-local storage: 44 private final ThreadLocal<Reference<K>> ctxTL 45 = new ThreadLocal<Reference<K>>(); 46 47 // ReentrantContext CLQ provider for child contexts: 48 private final ReentrantContextProviderCLQ<K> ctxProviderCLQ; 49 50 /** 51 * Create a new ReentrantContext provider using the given reference type 52 * among hard, soft or weak. 53 * It uses weak reference for the child contexts. 54 * 55 * @param refType reference type 56 */ 57 public ReentrantContextProviderTL(final int refType) { 58 this(refType, REF_WEAK); 59 } 60 61 /** 62 * Create a new ReentrantContext provider using the given reference types 63 * among hard, soft or weak 64 * 65 * @param refTypeTL reference type used by ThreadLocal 66 * @param refTypeCLQ reference type used by ReentrantContextProviderCLQ 67 */ 68 public ReentrantContextProviderTL(final int refTypeTL, final int refTypeCLQ) 69 { 70 super(refTypeTL); 71 72 final ReentrantContextProviderTL<K> parent = this; 73 74 this.ctxProviderCLQ = new ReentrantContextProviderCLQ<K>(refTypeCLQ) { 75 @Override 76 protected K newContext() { 77 return parent.newContext(); 78 } 79 }; 80 } 81 82 /** 83 * Give a ReentrantContext instance for the current thread 84 * 85 * @return ReentrantContext instance 86 */ 87 @Override 88 public final K acquire() { 89 K ctx = null; 90 final Reference<K> ref = ctxTL.get(); 91 if (ref != null) { 92 ctx = ref.get(); 93 } 94 if (ctx == null) { 95 // create a new ReentrantContext if none is available 96 ctx = newContext(); 97 // update thread local reference: 98 ctxTL.set(getOrCreateReference(ctx)); 99 } 100 // Check reentrance: 101 if (ctx.usage == USAGE_TL_INACTIVE) { 102 ctx.usage = USAGE_TL_IN_USE; 103 } else { 104 // get or create another ReentrantContext from CLQ provider: 105 ctx = ctxProviderCLQ.acquire(); 106 } 107 return ctx; 108 } 109 110 /** 111 * Restore the given ReentrantContext instance for reuse 112 * 113 * @param ctx ReentrantContext instance 114 */ 115 @Override 116 public final void release(final K ctx) { 117 if (ctx.usage == USAGE_TL_IN_USE) { 118 ctx.usage = USAGE_TL_INACTIVE; 119 } else { 120 ctxProviderCLQ.release(ctx); 121 } 122 } 123} 124