001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.memory;
016    
017    import com.liferay.portal.kernel.util.CentralizedThreadLocal;
018    
019    import java.lang.ref.SoftReference;
020    
021    /**
022     * @author Shuyang Zhou
023     */
024    public class SoftReferenceThreadLocal<T> extends CentralizedThreadLocal<T> {
025    
026            public SoftReferenceThreadLocal() {
027                    super(false);
028            }
029    
030            @Override
031            public T get() {
032                    SoftReference<T> softReference = _softReferenceThreadLocal.get();
033    
034                    if (softReference == _nullSoftReference) {
035                            return null;
036                    }
037    
038                    T value = null;
039    
040                    if (softReference != null) {
041                            value = softReference.get();
042                    }
043    
044                    if (value == null) {
045                            value = initialValue();
046    
047                            set(value);
048                    }
049    
050                    return value;
051            }
052    
053            @Override
054            public void remove() {
055                    _softReferenceThreadLocal.remove();
056            }
057    
058            @Override
059            public void set(T value) {
060                    if (value == null) {
061                            _softReferenceThreadLocal.set((SoftReference<T>)_nullSoftReference);
062                    }
063                    else {
064                            _softReferenceThreadLocal.set(new SoftReference<T>(value));
065                    }
066            }
067    
068            private static SoftReference<Object> _nullSoftReference =
069                    new SoftReference<Object>(null);
070    
071            private ThreadLocal<SoftReference<T>> _softReferenceThreadLocal =
072                    new CentralizedThreadLocal<SoftReference<T>>(false);
073    
074    }