alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (FastThreadLocal.java)

This example Java source code file (FastThreadLocal.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

boolean, exception, fastthreadlocal, identityhashmap, internalthreadlocalmap, object, set, suppresswarnings, unusedparameters, util

The FastThreadLocal.java Java example source code

/*
 * Copyright 2014 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package io.netty.util.concurrent;

import io.netty.util.internal.InternalThreadLocalMap;
import io.netty.util.internal.PlatformDependent;

import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Set;

/**
 * A special variant of {@link ThreadLocal} that yields higher access performance when accessed from a
 * {@link FastThreadLocalThread}.
 * <p>
 * Internally, a {@link FastThreadLocal} uses a constant index in an array, instead of using hash code and hash table,
 * to look for a variable.  Although seemingly very subtle, it yields slight performance advantage over using a hash
 * table, and it is useful when accessed frequently.
 * </p>

* To take advantage of this thread-local variable, your thread must be a {@link FastThreadLocalThread} or its subtype. * By default, all threads created by {@link DefaultThreadFactory} are {@link FastThreadLocalThread} due to this reason. * </p>

* Note that the fast path is only possible on threads that extend {@link FastThreadLocalThread}, because it requires * a special field to store the necessary state. An access by any other kind of thread falls back to a regular * {@link ThreadLocal}. * </p> * * @param <V> the type of the thread-local variable * @see ThreadLocal */ public class FastThreadLocal<V> { private static final int variablesToRemoveIndex = InternalThreadLocalMap.nextVariableIndex(); /** * Removes all {@link FastThreadLocal} variables bound to the current thread. This operation is useful when you * are in a container environment, and you don't want to leave the thread local variables in the threads you do not * manage. */ public static void removeAll() { InternalThreadLocalMap threadLocalMap = InternalThreadLocalMap.getIfSet(); if (threadLocalMap == null) { return; } try { Object v = threadLocalMap.indexedVariable(variablesToRemoveIndex); if (v != null && v != InternalThreadLocalMap.UNSET) { @SuppressWarnings("unchecked") Set<FastThreadLocal variablesToRemove = (Set>) v; FastThreadLocal<?>[] variablesToRemoveArray = variablesToRemove.toArray(new FastThreadLocal[variablesToRemove.size()]); for (FastThreadLocal<?> tlv: variablesToRemoveArray) { tlv.remove(threadLocalMap); } } } finally { InternalThreadLocalMap.remove(); } } /** * Returns the number of thread local variables bound to the current thread. */ public static int size() { InternalThreadLocalMap threadLocalMap = InternalThreadLocalMap.getIfSet(); if (threadLocalMap == null) { return 0; } else { return threadLocalMap.size(); } } /** * Destroys the data structure that keeps all {@link FastThreadLocal} variables accessed from * non-{@link FastThreadLocalThread}s. This operation is useful when you are in a container environment, and you * do not want to leave the thread local variables in the threads you do not manage. Call this method when your * application is being unloaded from the container. */ public static void destroy() { InternalThreadLocalMap.destroy(); } @SuppressWarnings("unchecked") private static void addToVariablesToRemove(InternalThreadLocalMap threadLocalMap, FastThreadLocal<?> variable) { Object v = threadLocalMap.indexedVariable(variablesToRemoveIndex); Set<FastThreadLocal variablesToRemove; if (v == InternalThreadLocalMap.UNSET || v == null) { variablesToRemove = Collections.newSetFromMap(new IdentityHashMap<FastThreadLocal()); threadLocalMap.setIndexedVariable(variablesToRemoveIndex, variablesToRemove); } else { variablesToRemove = (Set<FastThreadLocal) v; } variablesToRemove.add(variable); } private static void removeFromVariablesToRemove( InternalThreadLocalMap threadLocalMap, FastThreadLocal<?> variable) { Object v = threadLocalMap.indexedVariable(variablesToRemoveIndex); if (v == InternalThreadLocalMap.UNSET || v == null) { return; } @SuppressWarnings("unchecked") Set<FastThreadLocal variablesToRemove = (Set>) v; variablesToRemove.remove(variable); } private final int index; public FastThreadLocal() { index = InternalThreadLocalMap.nextVariableIndex(); } /** * Returns the current value for the current thread */ public final V get() { return get(InternalThreadLocalMap.get()); } /** * Returns the current value for the specified thread local map. * The specified thread local map must be for the current thread. */ @SuppressWarnings("unchecked") public final V get(InternalThreadLocalMap threadLocalMap) { Object v = threadLocalMap.indexedVariable(index); if (v != InternalThreadLocalMap.UNSET) { return (V) v; } return initialize(threadLocalMap); } private V initialize(InternalThreadLocalMap threadLocalMap) { V v = null; try { v = initialValue(); } catch (Exception e) { PlatformDependent.throwException(e); } threadLocalMap.setIndexedVariable(index, v); addToVariablesToRemove(threadLocalMap, this); return v; } /** * Set the value for the current thread. */ public final void set(V value) { if (value != InternalThreadLocalMap.UNSET) { set(InternalThreadLocalMap.get(), value); } else { remove(); } } /** * Set the value for the specified thread local map. The specified thread local map must be for the current thread. */ public final void set(InternalThreadLocalMap threadLocalMap, V value) { if (value != InternalThreadLocalMap.UNSET) { if (threadLocalMap.setIndexedVariable(index, value)) { addToVariablesToRemove(threadLocalMap, this); } } else { remove(threadLocalMap); } } /** * Returns {@code true} if and only if this thread-local variable is set. */ public final boolean isSet() { return isSet(InternalThreadLocalMap.getIfSet()); } /** * Returns {@code true} if and only if this thread-local variable is set. * The specified thread local map must be for the current thread. */ public final boolean isSet(InternalThreadLocalMap threadLocalMap) { return threadLocalMap != null && threadLocalMap.isIndexedVariableSet(index); } /** * Sets the value to uninitialized; a proceeding call to get() will trigger a call to initialValue(). */ public final void remove() { remove(InternalThreadLocalMap.getIfSet()); } /** * Sets the value to uninitialized for the specified thread local map; * a proceeding call to get() will trigger a call to initialValue(). * The specified thread local map must be for the current thread. */ @SuppressWarnings("unchecked") public final void remove(InternalThreadLocalMap threadLocalMap) { if (threadLocalMap == null) { return; } Object v = threadLocalMap.removeIndexedVariable(index); removeFromVariablesToRemove(threadLocalMap, this); if (v != InternalThreadLocalMap.UNSET) { try { onRemoval((V) v); } catch (Exception e) { PlatformDependent.throwException(e); } } } /** * Returns the initial value for this thread-local variable. */ protected V initialValue() throws Exception { return null; } /** * Invoked when this thread local variable is removed by {@link #remove()}. */ protected void onRemoval(@SuppressWarnings("UnusedParameters") V value) throws Exception { } }

Other Java examples (source code examples)

Here is a short list of links related to this Java FastThreadLocal.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.