mirror of
https://github.com/apache/openjpa.git
synced 2025-02-21 17:45:51 +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;
|
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.jdbc.schema.Column;
|
||||||
|
import org.apache.openjpa.lib.util.FlexibleThreadLocal;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,7 +52,7 @@ public class BindParameter {
|
|||||||
private final Column _column;
|
private final Column _column;
|
||||||
// key of this parameter
|
// key of this parameter
|
||||||
private final Object _key;
|
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.
|
* Constructs a parameter with given key, column and user flag.
|
||||||
@ -70,7 +68,7 @@ public class BindParameter {
|
|||||||
_key = key;
|
_key = key;
|
||||||
_user = user;
|
_user = user;
|
||||||
_column = column;
|
_column = column;
|
||||||
_value.put(Thread.currentThread(), value);
|
_values.set(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,26 +78,14 @@ public class BindParameter {
|
|||||||
* to this parameter.
|
* to this parameter.
|
||||||
*/
|
*/
|
||||||
public Object getValue() {
|
public Object getValue() {
|
||||||
Thread current = Thread.currentThread();
|
return _values.get();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Binds the given value to this parameter. Can be null.
|
* Binds the given value to this parameter. Can be null.
|
||||||
*/
|
*/
|
||||||
public void setValue(Object value) {
|
public void setValue(Object value) {
|
||||||
_value.put(Thread.currentThread(),value);
|
_values.set(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -124,8 +110,4 @@ public class BindParameter {
|
|||||||
return _key;
|
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