This is my first foray into multi threaded land and I'm currently implementing a solution using the Java concurrency library. The code essentially takes in a number of service requests, submits all the requests asynchronously and returns a map of responses when all services have completed. My code looks something like this:
public OuterClass {
public IResponseMap sendAsynchronousRequests(IRequest... dataList) {
List<RepositoryFutureTask<IRequest>> futures = new ArrayList<RepositoryFutureTask<IRequest>>();
//create one future for each request in the list
for (final IRequest request : dataList) {
RepositoryFutureTask<IRequest> future = new RepositoryFutureTask<IRequest>(request.getId(), new Callable<IRequest>() {
public IResponse call() {
return request.getService().callService(request.getRequestData());
}
});
futures.add(future);
}
//Submit each future for execution
for(Future future:futures) {
//Singleton ReqeustExecutorService maintains a pool of threads via
// java.util.concurrent.ExecutorService
RequestExecutorService.execute(future);
}
//Block processing until all requests have finished and add responses to map
//based on id as they finish
IResponseMap responseMap = new ResponseMap();
for(RepositoryFutureTask future:futures) {
responseMap.put(future.getId(), future.get());
}
return responseMap;
}
static class RepositoryFutureTask extends FutureTask<IResponse> {
private String id;
public RepositoryFutureTask(String theId, Callable<IResponse> callable) {
super(callable);
id = theId;
}
//standard getter for id omitted for conciseness
}
}
I'm primarily interested if my static inner class solution will create any issues in a multi threaded enviroment, but would also be interested in any other comments on the above solution. Note that there's a chance the code above isn't perfect as its still somewhat pseudo code and I've generified it a lot. Error handling has also been removed. Thanks in advance.
No, static inner classes are loaded in a manner equivalent to a top level classes. See 8.5.2 of the JLS -- http://java.sun.com/docs/books/jls/third_edition/html/classes.html
If you have a synchronized static method in a static nested class, it will be a lock on a different object to the same in the outer class. I would really recommend the synchronized modifier on any method, and particularly on a static method.
More a problem with anonymous inner classes, locks on this will be different. Even if you write synchronized (this) { it really isn't that obvious. I have seen it done a few times.
Theoretically I guess you could potentially run into trouble if the nested class static initialiser ran in parallel to the outer nester class static initialiser. Technically this is the same as running static intiailsers in two outer classes, but you are more likely to have cyclic dependencies with nested classes.
No issues with using static inner class. The only issues is that private String id; is not final. Make it final and you'll be alright with thread-safety ;-)
Related
I have a utility class as follows:
public class MetaUtility {
private static final SparseArray<MetaInfo> metaInfo = new SparseArray<>();
public static void flush() {
metaInfo.clear();
}
public static void addMeta(int key, MetaInfo info) {
if(info == null) {
throw new NullPointerException();
}
metaInfo.append(key, info);
}
public static MetaInfo getMeta(int key) {
return metaInfo.get(key);
}
}
This class is very simple and I wanted to have a "central" container to be used across classes/activities.
The issue is threading.
Right now it is populated (i.e the addMeta is called) only in 1 place in the code (not in the UI thread) and that is not going to change.
The getter is accessed by UI thread and in some cases by background threads.
Carefully reviewing the code I don't think that I would end up with the case that the background thread would add elements to the sparse array while some other thread would try to access it.
But this is very tricky for someone to know unless he knew the code very well.
My question is, how could I design my class so that I can safely use it from all threads including UI thread?
I can't just add a synchronized or make it block because that would block the UI thread. What can I do?
You should just synchronize on your object, because what your class is right now is just a wrapper class around a SparseArray. If there are thread level blocking issues, they would be from misuse of this object (well, I guess class considering it only exposes public static methods) in some other part of your project.
First shoot can be with synchronized.
#Jim What about the thread scheduling latency?
Android scheduler is based on Linux and it is known as a completely fair scheduler (CFS). It is "fair" in the sense that it tries to balance the execution of tasks not only based on the priority of the thread but also by tracking the amount of execution time that has been given to a thread.
If you'll see "Skipped xx frames! The application may be doing too much work on its main thread", then need some optimisations.
If you have uncontended lock you should not be afraid of using synchronized. In this case lock should be thin, which means that it would not pass blocked thread to OS scheduler, but would try to acquire lock again a few instructions after. But if you still would want to write non-blocking implementation, then you could use AtomicReference for holding the SparseArray<MetaInfo> array and update it with CAS.
The code might be smth like this:
static AtomicReference<SparseArray<MetaInfo>> atomicReference = new AtomicReference<>();
public static void flush() {
atomicReference.set(new SparseArray<MetaInfo>);
}
public static void addMeta(int key, MetaInfo info) {
if(info == null) {
throw new NullPointerException();
}
do {
SparseArray<MetaInfo> current = atomicReference.get();
SparseArray<MetaInfo> newArray = new SparseArray<MetaInfo>(current);
// plus add a new info
} while (!atomicReference.compareAndSet(current, newArray));
}
public static MetaInfo getMeta(int key) {
return atomicReference.get().get(key);
}
I have a Thread scenerio , in which 3 classes are MainThread.java,NormalWorkerClass1.java,NormalWorkerClass2.java
1 class:
class MainThread implements Runnable
{
private Thread thread = null;
//private variables
..
..
//default Constructor
public MainThread(){}
public MainThread(int val){
this.val=val;
}
public void start() {
thread = new Thread(this,"rootthread");
thread.start();
}
#Override
public void run() {
NormalWorkerClass1 instance1=NormalWorkerClass1.getInstance(); // Normal class
NormalWorkerClass2 instance2=NormalWorkerClass2.getInstance(); // for other working
try
{
while(true)
{
boolean retval=proccessSomething();
if(retval)
{
instance1.doMainProcess(arg..);
}
else
{
instance2.doMainProcess(arg..);
}
}
}
}
2 class:
class NormalWorkerClass1
{
private ...
private variables
public static NormalWorkerClass1 getInstance() {
return new NormalWorkerClass1();
}
public void doMainProcess(arg..)
{
Files processing()
// same common methods in NormalWorkerClass2
UtilityAccess ad=UtilityAccess.getInstance();
ad.Web Service part()
ad.dB part()
ad.Mail sending()
}
}
3 class:
class NormalWorkerClass2
{
private ...
private variables
public static NormalWorkerClass2 getInstance() {
return new NormalWorkerClass2();
}
public void doMainProcess(arg..)
{
Files processing()
// same common methods in NormalWorkerClass1
UtilityAccess ad=UtilityAccess.getInstance();
ad.Web Service part()
ad.dB part()
ad.Mail sending()
}
}
These are 3 classes.
My doubts are:
1 )In a multi threading Environment , i.e. if both class 2 and class 3 accessed at same time , whether
2 and 3 class cause any concurrency issue, because both are using some common methods and classes?
There is no Synchronisation part in this.
The web service part consists of another thread part.
2) What will happen when multiple thread access this,
NormalWorkerClass1 instance1=NormalWorkerClass1.getInstance(); // Normal class
NormalWorkerClass2 instance2=NormalWorkerClass2.getInstance(); // for other working
because its getInstance() method is a static method ,
multiple threads will share NormalWorkerClass1 and NormalWorkerClass2 class object values ?
5)Both classes NormalWorkerClass1 and NormalWorkerClass2 calls same common methods.. for e.g.. web service part.. if a thread1 enters into web service part and takes some time to complete ..on that particular moment another thread2 came to use web service part..this might cause any problem in total execution . same case with mail part also..will cause any issue in object clashing. I know each thread has its own stack for execution and have copies of variables
4) Can this Code cause any performance bottleneck? If yes ,How can I improve this code for multi threading and performance improving environment. ?
as i am new to this threading concurrency part..
Where concurrency causes problems is when multiple threads access shared state, your example doesn't have any shared state, it just shows static methods returning new instances of things. If you add static class variables that are accessed concurrently then you will have to worry about thread-safety issues with threads overwriting each others' work or with changes not being visible to other threads.
Calling methods doesn't in itself introduce concurrency problems, accessing and changing the contents of instance and class variables is what causes problems.
Nathan's Hughes answer is correct. I would add that there may be a concurrency problem if your run() method touches any instance variables of the MainThread class.
And one more thing - maybe obvious, maybe not: concurrency is about threads, not classes. Both NormalWorkerClass1 and NormalWorkerClass2 cannot conflict with each other when they are called from the same thread.
There are two good (as considered by most) java practices that i try to combine and fail.
Never leak this in a constructor.
Use enum instead of singleton pattern.
So, I want a singleton that as soon as created, listens for some event. Here's an example. First, the event listener interface:
public interface EventListener {
void doSomething();
}
Then, the event producer:
public class EventProducer implements Runnable{
private EventListener listener;
public EventProducer(EventListener listener) {
if (listener == null) {
throw new NullPointerException("Listener should not be null.");
}
this.listener = listener;
}
#Override
public void run() {
listener.doSomething(); //This may run before the listener is initialized.
do {
long startTime = System.currentTimeMillis();
long currentTime;
do {
currentTime = System.currentTimeMillis();
} while ((currentTime - startTime) < 1000);
listener.doSomething();
} while (!Thread.currentThread().isInterrupted());
listener = null; //Release the reference so the listener may be GCed
}
}
Then, the enum (as the 2nd listed java practice suggests):
public enum ListenerEnum implements EventListener{
INSTANCE;
private int counter;
private final ExecutorService exec;
private ListenerEnum() {
EventProducer ep = new EventProducer(this); //Automatically unregisters when the producer is done.
counter = 0;
exec = Executors.newSingleThreadExecutor();
exec.submit(ep);
}
#Override
public void doSomething() {
System.out.println("Did something.");
counter++;
if (counter >= 5) {
exec.shutdownNow();
}
}
}
And finally, something to get things started:
public class TestRunner {
public static void main(String[] args) {
ListenerEnum.INSTANCE.doSomething();
}
}
The problem lies in the first line of the ListenerEnum constructor, as we are leaking this, thus not conforming to the 1st listed java practice. This is why our event producer can call a listener's method before the listener is constructed.
How do I deal with this? Normally I would use a Builder pattern, but how is that possible with an enum?
EDIT:
For those that it matters, the event producer in my program actually extends a BroadcastReceiver, so my enum cannot be the event producer, they have to be separate. The producer is created in the constructor of the enum (as the example) and is registered programmatically later on. So I don't actually have a problem leaking this. Nevertheless, I'd like to know if I could avoid it.
EDIT 2:
Ok, since there are suggestions to solve my problem, i'd like to clarify some things. First of all, most suggestions are workarounds. They suggest doing the same thing in a completely different way. I appreciate the suggestions, and probably will accept one as answer and implement it. But the real question should be "How do i implement a Builder pattern with an enum?" The answer i already know and people suggest is "You don't, do it some other way.". Is there anyone who can post something like "You do! You do it this way."?
I was asked to give code close to my actual use case. Modify the following:
public enum ListenerEnum implements EventListener{
INSTANCE;
private EventProducer ep;
private int counter;
private ExecutorService exec;
private ListenerEnum() {
ep = new EventProducer(this); //Automatically unregisters when the producer is done.
counter = 0;
}
public void startGettingEvents() {
exec = Executors.newSingleThreadExecutor();
exec.submit(ep);
}
public void stopGettingEvents() {
exec.shutdownNow();
}
#Override
public void doSomething() {
System.out.println("Did something.");
counter++;
if (counter >= 5) {
stopGettingEvents();
}
}
}
As well as this:
public class TestRunner {
public static void main(String[] args) {
ListenerEnum.INSTANCE.startGettingEvents();
}
}
Now all i have to do to solve my problem is move the EventsProducer creation to the startGettingEvents() method. That's it. But that is also a workaround. What i'd like to know is: In general, how do you avoid leaking this in the constructor of a listener enum since you can't use the Builder pattern? Or can you actually someway use the Builder pattern with an enum? Is it done only by workarounds in a case by case basis? Or is there a general way to deal with this that i don't know of?
Just create a static initialization block:
public enum ListenerEnum implements EventListener{
INSTANCE;
private int counter;
private static final ExecutorService exec; //this looks strange. I'd move this service out of enum.
private static final EventProducer ep;
static{
exec = Executors.newSingleThreadExecutor();
ep = new EventProducer(INSTANCE); //Automatically unregisters when the producer is done.
exec.submit(ep);
}
#Override
public void doSomething() {
System.out.println("Did something.");
counter++;
if (counter >= 5) {
exec.shutdownNow();
}
}
}
As long as enum values are final and static they are initialized before the static initialization block. If you decompile the enum you'll see a single initialization block:
static{
INSTANCE = new ListenerEnum();
exec.submit(INSTANCE.ep);
}
First, consider why this shouldn’t escape:
You loose the final field safe publication guaranty in case of an improper publication of the instance
Even with a safe publication there are inconsistencies regarding all action not performed within the constructor at the time of the leakage
You will let escape an incomplete instance in case of subclasses as the subclass’ constructor hasn’t been called so far
That doesn’t apply to you in this narrow case. Submitting to an Executor is not an improper publication and enum’s can’t escape in any other way besides the one you have implemented yourself in the constructor. And its the last thing in the constructor whereas enums can’t have subclasses.
Now that you have edited your question, it makes much lesser sense. The constructor
private ListenerEnum() {
ep = new EventProducer(this);
counter = 0;
}
is not a “leaking this” as long as ep is not a static variable and the constructor of EventProducer does not let leak its this as well. This is important as programmers must be able to create circular object graphs without fearing sudden inconsistencies.
But it is still nothing you should take too easy. As said, it relies on the behavior of the EventProducer regarding leakage and regarding that EventProducer must not call back into ListenerEnum which could break things without being a “leaking this”, technically. After all, you can create code that breaks without breaking thread safety.
So it’s code for which you can’t see the correctness when looking at it as you need knowledge about another class.
There are use cases where passing this to another object is considered safe because of well-known behavior, e.g. weakThis=new WeakReference(this); is a real-life example. However, passing this to something called EventProducer is likely to let alarm bells ringing for every reader which you should avoid even if you know for sure that it’s false-alarm.
However, the big design smell lies in the use of the Singleton pattern in itself. After all, every instance you create is unique in the first place. What is special about the Singleton pattern is that it provides global public access to that instance. Is that really what you want? Did you consider that by using the Singleton pattern, everyone inside the entire application could register that listener again?
The fact that your class is a singleton (whether enum-based or otherwise) is unrelated to your problem. Your problem is simply how to register a listener within the constructor of an object. And the answer is: it's not possible, safely.
I would recommend you do two things:
Ensure your listener doesn't miss out on events by having a queue that it polls for work. This way, if it temporarily isn't listening, the work just queues up. In fact, this means it doesn't really need to be a listener in the traditional sense. It just needs to poll on a queue.
Register the class as a listener using a separate method, as discussed in the comments.
I would give some thought to avoiding a singleton. It doesn't offer many advantages (asides from the minor benefit of being able to call SomeClass.INSTANCE from anywhere). The downsides are most strongly felt during testing, where you find it much harder to mock the class when you wish to test without actually sending things over the network.
Here's a concrete example of why leaking this is dangerous in your case. Your constructor passes this before setting counter to zero:
private ListenerEnum() {
ep = new EventProducer(this);
counter = 0;
}
Now, as soon as this escapes, your event producer might invoke doSomething() 5 times before the constructor completes:
#Override
public void doSomething() {
System.out.println("Did something.");
counter++;
if (counter >= 5) {
exec.shutdownNow();
}
}
The sixth call to this method ought to fail right? Except that your constructor now finishes and sets counter = 0;. Thus allowing the producer to call doSomething() 5 more times.
Note: it doesn't matter if you reorder those lines as the constructor may not be executed in the order it appears in your code.
I want to synchronize method calls on basis some id i.e. something like a concurrency Decorator of a given object instance.
For example:
All threads which call the method with param "id1", should execute serially to one another.
All of the rest, which call the method with different argument, say "id2", should execute in parallel to the threads which call the method with param "id1", but again serially to each other.
So in my mind this can be implemented by having a lock (http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/locks/ReentrantLock.html) instance per such method param.
Each time the method is called with the param, the lock instance corresponding to the specific param value (e.g. "id1") would be looked up and the current thread would try to obtain the lock.
Speaking in code:
public class ConcurrentPolicyWrapperImpl implements Foo {
private Foo delegate;
/**
* Holds the monitor objects used for synchronization.
*/
private Map<String, Lock> concurrentPolicyMap = Collections.synchronizedMap(new HashMap<String, Lock>());
/**
* Here we decorate the call to the wrapped instance with a synchronization policy.
*/
#Override
public Object callFooDelegateMethod (String id) {
Lock lock = getLock(id);
lock.lock();
try {
return delegate.delegateMethod(id);
} finally {
lock.unlock();
}
}
protected Lock getLock(String id) {
Lock lock = concurrentPolicyMap.get(id);
if (lock == null) {
lock = createLock();
concurrentPolicyMap.put(id, lock);
}
return lock;
}
}
protected Lock createLock() {
return new ReentrantLock();
}
It seems that this works - I did some performance testing with jmeter and so on.
Still, as we all know concurrency in Java is a tricky thing, I decided to ask for your opinion here.
I can't stop thinking that there could be a better way to accomplish this. For example by using one of the BlockingQueue implementations. What do you think?
I also can't really decide for sure if there is a potential synchronization problem with getting the lock i.e. the protected Lock getLock(String id) method. I am using a synchronized collection, but is that enough? I.e. shouldn't it be something like the following instead of what I currently have:
protected Lock getLock(String id) {
synchronized(concurrentPolicyMap) {
Lock lock = concurrentPolicyMap.get(id);
if (lock == null) {
lock = createLock();
concurrentPolicyMap.put(id, lock);
}
return lock;
}
}
So what do you guys think?
Lock creation issues aside, the pattern is OK except that you may have an unbounded number of locks. Generally people avoid this by creating/using a Striped lock. There is a good/simple implementation in the guava library.
Application area of lock-striping
How to acquire a lock by a key
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/util/concurrent/Striped.html
Example code using guava implementation:
private Striped<Lock> STRIPPED_LOCK = Striped.lock(64);
public static void doActualWork(int id) throws InterruptedException {
try {
STRIPPED_LOCK.get(id).lock();
...
} finally {
STRIPPED_LOCK.get(id).unlock();
}
}
Though I would personally prefer Guava's Striped<Lock> approach suggested by Keith, just for discussion & completeness, I'd like to point out that using a Dynamic Proxy, or the more generic AOP (Aspect Oriented Programming), is one approach.
So we would define an IStripedConcurrencyAware interface that would serve as the "something like a concurrency Decorator" that you desire, and the Dynamic Proxy / AOP method hijacking based on this interface would de-multiplex the method call into the appropriate Executor / Thread.
I personally dislike AOP (or most of Spring, for that matter) because it breaks the what-you-see-is-what-you-get simplicity of Core Java, but YMMV.
I'd like to see if there's a good pattern for sharing a context across all classes and subthreads of a top-level thread without using InheritableThreadLocal.
I've got several top-level processes that each run in their own thread. These top-level processes often spawn temporary subthreads.
I want each top level process to have and manage it's own database connection.
I do not want to pass around the database connection from class to class and from thread to subthread (my associate calls this the "community bicycle" pattern). These are big top-level processes and it would mean editing probably hundreds of method signatures to pass around this database connection.
Right now I call a singleton to get the database connection manager. The singleton uses InheritableThreadLocal so that each top-level process has it's own version of it. While I know some people have problems with singletons, it means I can just say DBConnector.getDBConnection(args) (to paraphrase) whenever I need the correctly managed connection. I am not tied to this method if I can find a better and yet still-clean solution.
For various reasons InheritableThreadLocal is proving to be tricky. (See this question.)
Does anyone have a suggestion to handle this kind of thing that doesn't require either InheritableThreadLocal or passing around some context object all over the place?
Thanks for any help!
Update: I've managed to solve the immediate problem (see the linked question) but I'd still like to hear about other possible approaches. forty-two's suggestion below is good and does work (thanks!), but see the comments for why it's problematic. If people vote for jtahlborn's answer and tell me that I'm being obsessive for wanting to avoid passing around my database connection then I will relent, select that as my answer, and revise my world-view.
I haven't tested this, but the idea is to create a customized ThreadPoolExecutor that knows how to get the context object and use #beforeExecute() to transfer the context object to the thread that is going to execute the task. To be a nice citizen, you should also clear the context object in #afterEXecute(), but I leave that as an exercise.
public class XyzThreadPoolExecutor extends ThreadPoolExecutor {
public XyzThreadPoolExecutor() {
super(3, 3, 100, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), new MyThreadFactory());
}
#Override
public void execute(Runnable command) {
/*
* get the context object from the calling thread
*/
Object context = null;
super.execute(new MyRunnable(context, command));
}
#Override
protected void beforeExecute(Thread t, Runnable r) {
((MyRunnable)r).updateThreadLocal((MyThread) t);
super.beforeExecute(t, r);
}
private static class MyThreadFactory implements ThreadFactory {
#Override
public Thread newThread(Runnable r) {
return new MyThread(r);
}
}
private class MyRunnable implements Runnable {
private final Object context;
private final Runnable delegate;
public MyRunnable(Object context, Runnable delegate) {
super();
this.context = context;
this.delegate = delegate;
}
void updateThreadLocal(MyThread thread) {
thread.setContext(context);
}
#Override
public void run() {
delegate.run();
}
}
private static class MyThread extends Thread {
public MyThread(Runnable target) {
super(target);
}
public void setContext(Object context) {
// set the context object here using thread local
}
}
}
the "community bicycle" solution (as you call it) is actually much better than the global (or pseudo global) singleton that you are currently using. it makes the code testable and it makes it very easy to choose which classes use which context. if done well, you don't need to add the context object to every method signature. you generally ensure that all the "major" classes have a reference to the current context, and that any "minor" classes have access to the relevant "major" class. one-off methods which may need access to the context will need their method signatures updated, but most classes should have the context available through a member variable.
As a ThreadLocal is essentially a Map keyed on your thread, couldn't you implement a Map keyed on your thread name? All you then need is an effective naming strategy that meets your requirements.
As a Lisper, I very much agree with your worldview and would consider it a shame if you were to revise it. :-)
If it were me, I would simply use a ThreadGroup for each top-level process, and associate each connection with the group the caller is running in. If using in conjunction with thread pools, just ensure the pools use threads in the correct thread group (for instance, by having a pool per thread group).
Example implementation:
public class CachedConnection {
/* Whatever */
}
public class ProcessContext extends ThreadGroup {
private static final Map<ProcessContext, Map<Class, Object>> contexts = new WeakHashMap<ProcessContext, Map<Class, Object>>();
public static T getContext(Class<T> cls) {
ProcessContext tg = currentContext();
Map<Class, Object> ctx;
synchronized(contexts) {
if((ctx = contexts.get(tg)) == null)
contexts.put(tg, ctx = new HashMap<Class, Object>());
}
synchronized(ctx) {
Object cur = ctx.get(cls);
if(cur != null)
return(cls.cast(cur));
T new_t;
try {
new_t = cls.newInstance();
} catch(Exception e) {
throw(new RuntimeException(e));
}
ctx.put(cls, new_t);
return(new_t);
}
}
public static ProcessContext currentContext() {
ThreadGroup tg = Thread.currentThread().getThreadGroup();
while(true) {
if(tg instanceof ProcessContext)
return((ProcessContext)tg);
tg = tg.getParent();
if(tg == null)
throw(new IllegalStateException("Not running in a ProcessContext"));
}
}
}
If you then simply make sure to run all your threads in a proper ProcessContext, you can get a CachedConnection anywhere by calling ProcessContext.getContext(CachedConnection.class).
Of course, as mentioned above, you would have to make sure that any other threads you may delegate work to also run in the correct ProcessContext, but I'm pretty sure that problem is inherent in your description -- you would obviously need to specify somehow which one of multiple contexts your delegation workers run in. If anything, it could be conceivable to modify ProcessContext as follows:
public class ProcessContext extends ThreadGroup {
/* getContext() as above */
private static final ThreadLocal<ProcessContext> tempctx = new ThreadLocal<ProcessContext>();
public static ProcessContext currentContext() {
if(tempctx.get() != null)
return(tempctx.get());
ThreadGroup tg = Thread.currentThread().getThreadGroup();
while(true) {
if(tg instanceof ProcessContext)
return((ProcessContext)tg);
tg = tg.getParent();
if(tg == null)
throw(new IllegalStateException("Not running in a ProcessContext"));
}
}
public class RunnableInContext implements Runnable {
private final Runnable delegate;
public RunnableInContext(Runnable delegate) {this.delegate = delegate;}
public void run() {
ProcessContext old = tempctx.get();
tempctx.set(ProcessContext.this);
try {
delegate.run();
} finally {
tempctx.set(old);
}
}
}
public static Runnable wrapInContext(Runnable delegate) {
return(currentContext().new RunnableInContext(delegate));
}
}
That way, you could use ProcessContext.wrapInContext() to pass a Runnable which, when run, inherits its context from where it was created.
(Note that I haven't actually tried the above code, so it may well be full of typos.)
I would not support your world-view and jthalborn's idea on the count that its more testable even.
Though paraphrasing first what I have understood from your problme statement is like this.
There are 3 or 4 top-level processes (and they are basically having a thread of their own). And connection object is what is diffrenet in them.
You need some basic characteristic of Connection to be set up and done once.
The child threads in no way change the Connection object passe to them from top-level threads.
Here is what I propose, you do need the one tim,e set-up of you Connection but then in each of your top-level process, you do 1) further processing of that Connection 2) keep a InheriatbleThreadLocal (and the child process of your top-level thread will have the modified connection object. 3) Pass these threasd implementing classes. MyThread1, MyThread2, MyThread3, ... MyThread4 in the Executor. (This is different from the other linked question of yours that if you need some gating, Semaphore is a better approach)
Why I said that its not less testable than jthalborn's view is that in that case also you anyway again needs to provide mocked Connection object. Here too. Plus conecptually passing the object and keeping the object in ThreadLocal is one and the same (InheritableThreadLocal is a map which gets passed by java inbuilt way, nothing bad here I believe).
EDIT: I did keep in account that its a closed system and we are not having "free" threads tempring with connection