001
014
015 package com.liferay.portal.kernel.executor;
016
017 import com.liferay.portal.kernel.util.CentralizedThreadLocal;
018 import com.liferay.portal.kernel.util.ThreadLocalBinder;
019
020 import java.util.Collections;
021 import java.util.Map;
022 import java.util.concurrent.Callable;
023
024
027 public abstract class CopyThreadLocalCallable<T> implements Callable<T> {
028
029 public CopyThreadLocalCallable(boolean readOnly, boolean clearOnExit) {
030 this(null, readOnly, clearOnExit);
031 }
032
033 public CopyThreadLocalCallable(
034 ThreadLocalBinder threadLocalBinder, boolean readOnly,
035 boolean clearOnExit) {
036
037 _threadLocalBinder = threadLocalBinder;
038
039 if (_threadLocalBinder != null) {
040 _threadLocalBinder.record();
041 }
042
043 if (readOnly) {
044 _longLivedThreadLocals = Collections.unmodifiableMap(
045 CentralizedThreadLocal.getLongLivedThreadLocals());
046 _shortLivedlThreadLocals = Collections.unmodifiableMap(
047 CentralizedThreadLocal.getShortLivedThreadLocals());
048 }
049 else {
050 _longLivedThreadLocals =
051 CentralizedThreadLocal.getLongLivedThreadLocals();
052 _shortLivedlThreadLocals =
053 CentralizedThreadLocal.getShortLivedThreadLocals();
054 }
055
056 _clearOnExit = clearOnExit;
057 }
058
059 @Override
060 public final T call() throws Exception {
061 CentralizedThreadLocal.setThreadLocals(
062 _longLivedThreadLocals, _shortLivedlThreadLocals);
063
064 if (_threadLocalBinder != null) {
065 _threadLocalBinder.bind();
066 }
067
068 try {
069 return doCall();
070 }
071 finally {
072 if (_clearOnExit) {
073 if (_threadLocalBinder != null) {
074 _threadLocalBinder.cleanUp();
075 }
076
077 CentralizedThreadLocal.clearLongLivedThreadLocals();
078 CentralizedThreadLocal.clearShortLivedThreadLocals();
079 }
080 }
081 }
082
083 public abstract T doCall() throws Exception;
084
085 private final boolean _clearOnExit;
086 private final Map<CentralizedThreadLocal<?>, Object> _longLivedThreadLocals;
087 private final Map<CentralizedThreadLocal<?>, Object>
088 _shortLivedlThreadLocals;
089 private final ThreadLocalBinder _threadLocalBinder;
090
091 }