Setting ThreadContext for all threads in application - java

From this answer https://stackoverflow.com/a/25125159/4367326 I have routingAppender working but I want to set the ThreadContext for every thread in the program.
When I set
ThreadContext.put("logFileName", "TestLogFile");
it works for the main thread and logs as expected but not for any other threads in my application. How can I achieve this?

Every child thread will inherit fathers ThreadContext state if you set up system property isThreadContextMapInheritable to true. But this will not work for Executors so you need to manually copy data from one thread to another.
Update#2
You can do something like this:
public abstract class ThreadContextRunnable implements Runnable {
private final Map context = ThreadContext.getContext();
#Override
public final void run() {
if (context != null) {
ThreadContext.putAll(context);
}
try {
runWithContext();
} finally {
ThreadContext.clearAll();
}
}
protected abstract void runWithContext();
}
And then you only need to implement runWithContext method.

Related

ThreadFactory and newThread(Runnable r) how to access to the attributes of r if it is a Thread?

For my thesis I'm working on a Discrete Event System Simulator. The simulation consists in a set of SimulatorThread extends Thread whose action consist in scheduling Events to the Simulator. Each SimulatorThread interracts with the Simulator through the SimulatorInterface.
public abstract class SimulatorThread extends Thread {
private SimulatorInterface si;
public SimulatorThread(SimulatorInterface si) {
this.si = si;
}
...
}
public final class Simulator {
private ExecutorService exec;
...
public void assignThread(SimulatorThread... stList) {
...
}
}
Before the simulation begins, each SimulatorThread is assigned to the Simulator, then the Simulator will execute each thread through exec.execute(simulatorThread). My problem is that in some part of the code i need to get a reference to the current running SimulatorThread, but the instruction (SimulatorThread) Thread.currentThread() gives a cast execption. Infact the output of System.out.print(Thread.currentThread().getClass()) is class java.lang.Thread, but I would like that the output is class SimulatorThread which can be obtained by running the thread using the instruction simulatorThread.start() instead of using the executor. So I thought that the problem is in writing an ad-hoc ThreadFactory that return an instance of SimulatorThread.
Infact I tried to use the trivial SimulatorThreadFactory extends ThreadFactory:
public class SimulatorThreadFactory implements ThreadFactory {
#Override
public Thread newThread(Runnable r) {
return new SimulatorThread(new SimulatorInterface());
}
}
and with this I obtained the previously cited output 'class SimulatorThread'. The problem is that when I call 'exec.execute(simulatorThread)', the parameter has an attribute 'SimulatorInterface' to which I need to get access, but I can't becaues the parameter of the method 'newThread' is a 'Runnable'. I expose here a wrong code that I hope expresses what I mean better than how I explain in words:
public class SimulatorThreadFactory implements ThreadFactory {
#Override
public Thread newThread(Runnable r) {
SimulatorInterface si = r.getSimulatorInterface(); // this is what
// I would like
// the thread factory
// to do
return new SimulatorThread(si);
}
}
So, how can I access to attribute 'SimulatorInterface' of the 'SimulatorThread' inside the method newThread in order to create a SimulatorThread if its paramater is a Runnable?
If I understand your needs, the right way to do this is to not extend Thread but to implement Runnable. Then all of the benefits of your own class hierarchy can be enjoyed:
public abstract class SimulatorRunnable extends Runnable {
protected SimulatorInterface si;
public SimulatorRunnable(SimulatorInterface si) {
this.si = si;
}
}
public final class Simulator extends SimulatorRunnable {
public Simulator(SimulatorInterface si) {
super(si);
}
public void run() {
// here you can use the si
si.simulate(...);
}
}
Then you submit your simulator to your thread-pool:
Simulator simulator = new Simulator(si);
...
exec.submit(simulator);
My problem is that in some part of the code i need to get a reference to the current running SimulatorThread, but the instruction (SimulatorThread) Thread.currentThread() gives a cast execption
You should not be passing a Thread into an ExecutorService. It is just using it as a Runnable (since Thread implements Runnable) and the thread-pool starts its' own threads and will never call start() on your SimulatorThread. If you are extending Thread then you need to call thread.start() directly and not submit it to an ExecutorService. The above pattern of implements Runnable with an ExecutorService is better.
#Gray's answer is correct, pointing out that the ExecutorService is designed to use its own threads to execute your Runnables, and sometimes created threads will even be reused to run different Runnables.
Trying to get information from (SimulatorThread) Thread.currentThread() smells like a 'global variable' anti-pattern. Better to pass the 'si' variable along in method calls.
If you really want global variables that are thread-safe, use ThreadLocals:
public final class Simulator extends SimulatorRunnable {
public static final ThreadLocal<SimulatorInterface> currentSim = new ThreadLocal<>();
public Simulator(SimulatorInterface si) {
super(si);
}
public void run() {
currentSim.set(si)
try{
doStuff();
}
finally{
currentSim.unset();
}
}
private void doStuff()
{
SimulatorInterface si = Simulator.currentSim.get();
//....
}
}

Thread creation listener

Is it possible to write Thread creation listener in java? For example using aop?!
I mean something like this that if my application creates a thread I would like to register this object in my own table, container or something.
I would create a thread that continously lists all running threads on the JVM.
Then each time it noticies that a new thread has appeared, it would notify in either way a class in your code.
Here are some links about how to list all threads currently running on the JVM :
Get a List of all Threads currently running in Java
Listing All Running Threads
============
A starting code :
ThreadCreationListener.java
public interface ThreadCreationListener {
public void onThreadCreation(Thread newThread);
}
ThreadCreationMonitor.java
public class ThreadCreationMonitor extends Thread {
private List<ThreadCreationListener> listeners;
private boolean canGo;
public ThreadCreationMonitor() {
listeners = new Vector<ThreadCreationListener>();//Vector class is used because many threads may use a ThreadCreationMonitor instance.
canGo = true;
// Initialize the rest of the class here...
}
// Most important methods
public void addListener(ThreadCreationListener tcl) {
listeners.add(tcl);
}
public void removeListener(ThreadCreationListener tcl) {
listeners.remove(tcl);
}
public void run() {
List<Thread> runningThreads;
List<Thread> lastRunningThreads = new ArrayList<>();
while(canGo) {
// Step 1 - List all running threads (see previous links)
// runningThreads = ...
// Step 2 - Check for new threads and notify all listeners if necessary
if (runningThreads.removeAll(lastRunningThreads)==true) {
for(Thread t : runningThreads) {
for(ThreadCreationListener tcl : listeners) {
lastRunningThreads.add(t);
tcl.onThreadCreation(t); //Notify listener
}
}
}
}
}
public void shutdown() {
canGo = false;
}
}
MyThreadInfoConsumer.java
public class MyThreadInfoConsumer implements ThreadCreationListener {
public void onThreadCreation(Thread newThread) {
// Process here the notification...
}
}
Main.java
public class Main {
public static void main(String[] args) {
ThreadCreationMonitor tcm = new ThreadCreationMonitor();
tcm.start();
MyThreadInfoConsumer myTIC = new MyThreadInfoConsumer();
tcm.addListener(myTIC);
// rest of your code...
// Don't forget to call tcm.shutdown() when exiting your application !
}
}
I think this would be possible with AOP (aspectj for instance). But it is still required to create your own Thread and ThreadGroup/Executor types, unless you can recompile the JDK classes with the aspect compiler. Define the pointcut on your thread's start method if you want to register on thread launching or on the createThread of your pool if you want to register on the creation of the thread objects.
The following works only if you recompiled the JDK with the aspect compiler:
All threads are started with Thread.start, so write a pointcut for that method then you can use advices to do what you'd like to. Of course this is not perfect since e.g. a cachedThreadPool executor might not start a new thread for each task, but maybe if you register a pointcut on Runnable.run and Callable.call rather than on Thread.start, that might be sufficient enough.
Perhaps a ThreadGroup is what you need. All Threads are members of a ThreadGroup and when you start a new Thread it is added to the same group as its parent by default.
In theory its possible (but not recommended) to sub-class to be notified when a Thread is added or removed from the group.
It is likely that polling the threads of this groups, or polling all threads is a better solution.

How to Thread a complex Model class to provide synchronization with a Controller class?

How can I proceed in a controller based on whether just one part of a complex model has produced the correct flag?
A controller class is playing a queue of Midi sequences while holding onto an instance of a model class that is dynamically updated via user button presses. After the Midi queue ends, the controller needs to synchronize with the model to check that the user has made a certain number of entries before proceeding to update the interface and move to the next part of the application. The Model represents quite a lot of other data in addition to the ArrayList of user button presses, so the challenge is how to best compartmentalize the synchronization part.
Right now, the pattern I'm trying is something like the following, which doesn't work because of nested class access between the controller and the model:
//Controller
...
Thread entriesCoordination = new Thread( new Model.InnerClass);
entriesCoordination.start();
Thread t = new Thread (this);
t.run();
...
//in runnable nested class in controller
private Model.InncerClass c = new Model.InnerClass();
public void run() {
synchronized( c) {
while (!c.hasFinishedEntries()){
try{
c.wait();
} catch (InterruptedException ignore{}
}
}
}
//Midiqueue completed and Entries finished
}
//in Model
//in runnable nested class in Model
public synchronized boolean hasFinishedEntries() {
return fIsFinishedWithEntries;
}
public void run() {
while(true) {
try{
synchronized(this) {
try{
if(entriesArray.size() == max_size) {
fIsFinishedWithEntries = true;
notifyAll();
} else {...}
}
}
}
}
}
Furthermore, this seems wasteful because it basically means that I need to create a thread and run the inner class of the Model in parallel the entire duration of the time that the user can make these button selections, rather than something that would just poll the Model when I know that the Midi queue has ended.
What's the design pattern to synchronize to one flag in a Model class from a Controller class without having to make a inner class in the model just to handle the synchronization.
I think the right thing to do here is to use an AtomicBoolean and define methods on each of your thread objects to get and set the boolean.
The Model.InnerClass would be changed to add the AtomicBoolean and to change the getter to not be synchronized.
private final AtomicBoolean fIsFinishedWithEntries = new AtomicBoolean();
public boolean hasFinishedEntries() {
return fIsFinishedWithEntries.get();
}
In the run method it something needs to set the finished boolean to be true.
public void run() {
while(true) {
if (entriesArray.size() == max_size) {
synchronized (this) {
fIsFinishedWithEntries.set(true);
notifyAll();
}
} else {...}
}
}
}
You'll need to rest it to false somewhere if you are doing this more than once.
Right now, the pattern I'm trying is something like the following, which doesn't work because of nested class access between the controller and the model:
You need to first create your Model.InnerClass instance and inject that into your controller thread. Making the hasFinishedEntries() be static is ugly so instead in your controller you'd call:
private Model.InnerClass innerClass;
public ControllerThread(Model.InnerClass innerClass) {
this.innerClass = innerClass;
}
...
public void run() {
synchronized (innerClass) {
while (!innerClass.hasFinishedEntries()){
innerClass.wait();
}
}
}
How can I access whether the entries are finished without synchronizing on the entire Model class?
You can obviously just poll the hasFinishedEntries() whenever you want to see if the queue has ended. I'm not sure of a better way to do this without a thread. Is there some way to setup a UI event which checks for a condition every so often?

How to have a shared context per top-level process/thread without using InheritableThreadLocal?

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

Propagating ThreadLocal to a new Thread fetched from a ExecutorService

I'm running a process in a separate thread with a timeout, using an ExecutorService and a Future (example code here) (the thread "spawning" takes place in a AOP Aspect).
Now, the main thread is a Resteasy request. Resteasy uses one ore more ThreadLocal variables to store some context information that I need to retrieve at some point in my Rest method call. Problem is, since the Resteasy thread is running in a new thread, the ThreadLocal variables are lost.
What would be the best way to "propagate" whatever ThreadLocal variable is used by Resteasy to the new thread? It seems that Resteasy uses more than one ThreadLocal variable to keep track of context information and I would like to "blindly" transfer all the information to the new thread.
I have looked at subclassing ThreadPoolExecutor and using the beforeExecute method to pass the current thread to the pool, but I couldn't find a way to pass the ThreadLocal variables to the pool.
Any suggestion?
Thanks
The set of ThreadLocal instances associated with a thread are held in private members of each Thread. Your only chance to enumerate these is to do some reflection on the Thread; this way, you can override the access restrictions on the thread's fields.
Once you can get the set of ThreadLocal, you could copy in the background threads using the beforeExecute() and afterExecute() hooks of ThreadPoolExecutor, or by creating a Runnable wrapper for your tasks that intercepts the run() call to set an unset the necessary ThreadLocal instances. Actually, the latter technique might work better, since it would give you a convenient place to store the ThreadLocal values at the time the task is queued.
Update: Here's a more concrete illustration of the second approach. Contrary to my original description, all that is stored in the wrapper is the calling thread, which is interrogated when the task is executed.
static Runnable wrap(Runnable task)
{
Thread caller = Thread.currentThread();
return () -> {
Iterable<ThreadLocal<?>> vars = copy(caller);
try {
task.run();
}
finally {
for (ThreadLocal<?> var : vars)
var.remove();
}
};
}
/**
* For each {#code ThreadLocal} in the specified thread, copy the thread's
* value to the current thread.
*
* #param caller the calling thread
* #return all of the {#code ThreadLocal} instances that are set on current thread
*/
private static Collection<ThreadLocal<?>> copy(Thread caller)
{
/* Use a nasty bunch of reflection to do this. */
throw new UnsupportedOperationException();
}
Based on #erickson answer I wrote this code. It is working for inheritableThreadLocals. It builds list of inheritableThreadLocals using same method as is used in Thread contructor. Of course I use reflection to do this. Also I override the executor class.
public class MyThreadPoolExecutor extends ThreadPoolExecutor
{
#Override
public void execute(Runnable command)
{
super.execute(new Wrapped(command, Thread.currentThread()));
}
}
Wrapper:
private class Wrapped implements Runnable
{
private final Runnable task;
private final Thread caller;
public Wrapped(Runnable task, Thread caller)
{
this.task = task;
this.caller = caller;
}
public void run()
{
Iterable<ThreadLocal<?>> vars = null;
try
{
vars = copy(caller);
}
catch (Exception e)
{
throw new RuntimeException("error when coping Threads", e);
}
try {
task.run();
}
finally {
for (ThreadLocal<?> var : vars)
var.remove();
}
}
}
copy method:
public static Iterable<ThreadLocal<?>> copy(Thread caller) throws Exception
{
List<ThreadLocal<?>> threadLocals = new ArrayList<>();
Field field = Thread.class.getDeclaredField("inheritableThreadLocals");
field.setAccessible(true);
Object map = field.get(caller);
Field table = Class.forName("java.lang.ThreadLocal$ThreadLocalMap").getDeclaredField("table");
table.setAccessible(true);
Method method = ThreadLocal.class
.getDeclaredMethod("createInheritedMap", Class.forName("java.lang.ThreadLocal$ThreadLocalMap"));
method.setAccessible(true);
Object o = method.invoke(null, map);
Field field2 = Thread.class.getDeclaredField("inheritableThreadLocals");
field2.setAccessible(true);
field2.set(Thread.currentThread(), o);
Object tbl = table.get(o);
int length = Array.getLength(tbl);
for (int i = 0; i < length; i++)
{
Object entry = Array.get(tbl, i);
Object value = null;
if (entry != null)
{
Method referentField = Class.forName("java.lang.ThreadLocal$ThreadLocalMap$Entry").getMethod(
"get");
referentField.setAccessible(true);
value = referentField.invoke(entry);
threadLocals.add((ThreadLocal<?>) value);
}
}
return threadLocals;
}
As I understand your problem, you can have a look at InheritableThreadLocal which is meant to pass ThreadLocal variables from Parent Thread context to Child Thread Context
I don't like Reflection approach. Alternative solution would be to implement executor wrapper and pass object directly as a ThreadLocal context to all child threads propagating a parent context.
public class PropagatedObject {
private ThreadLocal<ConcurrentHashMap<AbsorbedObjectType, Object>> data = new ThreadLocal<>();
//put, set, merge methods, etc
}
==>
public class ObjectAwareExecutor extends AbstractExecutorService {
private final ExecutorService delegate;
private final PropagatedObject objectAbsorber;
public ObjectAwareExecutor(ExecutorService delegate, PropagatedObject objectAbsorber){
this.delegate = delegate;
this.objectAbsorber = objectAbsorber;
}
#Override
public void execute(final Runnable command) {
final ConcurrentHashMap<String, Object> parentContext = objectAbsorber.get();
delegate.execute(() -> {
try{
objectAbsorber.set(parentContext);
command.run();
}finally {
parentContext.putAll(objectAbsorber.get());
objectAbsorber.clean();
}
});
objectAbsorber.merge(parentContext);
}
Here is an example to pass the current LocaleContext in parent thread to the child thread spanned by CompletableFuture[By default it used ForkJoinPool].
Just define all the things you wanted to do in a child thread inside a Runnable block. So when the CompletableFuture execute the Runnable block, its the child thread who is in control and voila you have the parent's ThreadLocal stuff set in Child's ThreadLocal.
The problem here is not the entire ThreadLocal is copied over. Only the LocaleContext is copied. Since the ThreadLocal is of private access to only the Thread it belongs too using Reflection and trying to get and set in Child is all too much of wacky stuff which might lead to memory leaks or performance hit.
So if you know the parameters you are interested from the ThreadLocal, then this solution works way cleaner.
public void parentClassMethod(Request request) {
LocaleContext currentLocale = LocaleContextHolder.getLocaleContext();
executeInChildThread(() -> {
LocaleContextHolder.setLocaleContext(currentLocale);
//Do whatever else you wanna do
}));
//Continue stuff you want to do with parent thread
}
private void executeInChildThread(Runnable runnable) {
try {
CompletableFuture.runAsync(runnable)
.get();
} catch (Exception e) {
LOGGER.error("something is wrong");
}
}
If you look at ThreadLocal code you can see:
public T get() {
Thread t = Thread.currentThread();
...
}
current thread cannot be overwritten.
Possible solutions:
Look at java 7 fork/join mechanism (but i think it's a bad way)
Look at endorsed mechanism to overwrite ThreadLocal class in your JVM.
Try to rewrite RESTEasy (you can use Refactor tools in your IDE to replace all ThreadLocal usage, it's look like easy)

Categories