mirror of
https://github.com/apache/openjpa.git
synced 2025-02-20 17:05:15 +00:00
OPENJPA-2099: Introduce flexible ThreadLocal
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1235624 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ade97ac4d4
commit
f31e4ba507
@ -18,10 +18,8 @@
|
||||
*/
|
||||
package org.apache.openjpa.jdbc.sql;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.openjpa.jdbc.schema.Column;
|
||||
import org.apache.openjpa.lib.util.FlexibleThreadLocal;
|
||||
|
||||
|
||||
/**
|
||||
@ -54,7 +52,7 @@ public class BindParameter {
|
||||
private final Column _column;
|
||||
// key of this parameter
|
||||
private final Object _key;
|
||||
private Map<Thread, Object> _value = new HashMap<Thread, Object>();
|
||||
private FlexibleThreadLocal<Object> _values = new FlexibleThreadLocal<Object>();
|
||||
|
||||
/**
|
||||
* Constructs a parameter with given key, column and user flag.
|
||||
@ -70,7 +68,7 @@ public class BindParameter {
|
||||
_key = key;
|
||||
_user = user;
|
||||
_column = column;
|
||||
_value.put(Thread.currentThread(), value);
|
||||
_values.set(value);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -80,26 +78,14 @@ public class BindParameter {
|
||||
* to this parameter.
|
||||
*/
|
||||
public Object getValue() {
|
||||
Thread current = Thread.currentThread();
|
||||
if (!_value.containsKey(current)) {
|
||||
// calling thread may be a child of the thread that inserted the value.
|
||||
// This is for SliceThread
|
||||
for (Map.Entry<Thread, Object> e : _value.entrySet()) {
|
||||
if (isEquivalent(e.getKey(), current))
|
||||
return e.getValue();
|
||||
}
|
||||
throw new IllegalStateException("No value for " + current
|
||||
+ ". Known threads " + _value.keySet());
|
||||
|
||||
}
|
||||
return _value.get(current);
|
||||
return _values.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the given value to this parameter. Can be null.
|
||||
*/
|
||||
public void setValue(Object value) {
|
||||
_value.put(Thread.currentThread(),value);
|
||||
_values.set(value);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -124,8 +110,4 @@ public class BindParameter {
|
||||
return _key;
|
||||
}
|
||||
|
||||
boolean isEquivalent(Thread a, Thread b) {
|
||||
if (a == b) return true;
|
||||
return a.equals(b) || b.equals(a);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF 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 org.apache.openjpa.lib.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A thread-specific storage similar to {@link ThreadLocal}.
|
||||
*
|
||||
* @author Pinaki Poddar
|
||||
*
|
||||
*/
|
||||
public class FlexibleThreadLocal<T> {
|
||||
private final Map<Thread, T> _values = new HashMap<Thread, T>();
|
||||
|
||||
/**
|
||||
* Gets the value associated with the calling thread or its equivalent.
|
||||
*
|
||||
* @see #isEquivalent(Thread, Thread)
|
||||
*/
|
||||
public T get() {
|
||||
Thread current = Thread.currentThread();
|
||||
if (_values.containsKey(current)) {
|
||||
return _values.get(current);
|
||||
} else {
|
||||
for (Map.Entry<Thread, T> e : _values.entrySet()) {
|
||||
if (isEquivalent(e.getKey(), current))
|
||||
return e.getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates the value to the current thread.
|
||||
*/
|
||||
public T set(T t) {
|
||||
return _values.put(Thread.currentThread(), t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Affirms if the two given thread are equivalent.
|
||||
* Equivalence takes asymmetric equality in account.
|
||||
*/
|
||||
protected boolean isEquivalent(Thread a, Thread b) {
|
||||
if (a == b) return true;
|
||||
if (a == null || b== null) return false;
|
||||
return a.equals(b) || b.equals(a);
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user