I want to pass objects between methods within a thread without using a method signature.
Example:
public class Controller {
#GET
public void requestController() {
// set user data in the controller currentThread
}
}
public class Service {
public void serviceMethod() {
// get user data in the service method from currentThread
}
}
as Controller and Service are in the same thread, I should be able to access the object in Service that was set in the Controller.
MDC does follow the same approach using MDC.put and MDC.get but I am not sure which pattern it uses.
Youre looking for a ThreadLocal. MDC uses that internally.
Usage
The usage is pretty simple. You need one ThreadLocal Instance that is accessable by all components that need access to it. In most cases its simply a public static final variable.
public class SomeClass {
// use whatever class you want here, String for example
public static final ThreadLocal<String> TL_MESSAGE = new ThreadLocal<>();
}
public class Controller {
#GET
public void requestController() {
SomeClass.TL_MESSAGE.set("hello world");
try {
// everything after set should be wrapped in this try-finally-block
service.serviceMethod();// this can be anywhere in the code, it doesnt have to called here directly. As long as the thread is the same and the method is called between set and remove
} finally {
SomeClass.TL_MESSAGE.remove();
}
}
}
public class Service {
public void serviceMethod() {
String message = SomeClass.TL_MESSAGE.get();
}
}
Pitfall / Memory leak possibility!
Ensure that you always remove the value you set.
For more information, see: ThreadLocal & Memory Leak
Related
Given a Singleton like this one:
#Singleton
public class waitingTimeManager {
private Map<Integer, Object> waitingTimes;
#PostConstruct
public void setup() {
waitingTimes = new HashMap<>();
}
#Lock(LockType.READ)
public boolean shouldWeWait(Integer id) {
if (waitingTimes.containsKey(id)) {
boolean wait = someLogic(waitingTimes.get(id));
if (!wait) {
// we don't need to wait for it anymore
stopWaiting(id);
}
return wait;
}
return false;
}
#Lock(LockType.WRITE)
public void stopWaiting(Integer id){
waitingTimes.remove(id);
}
}
The initial method shouldWeWait can be accessed at the same time by several threads. The other stopWaiting will need to get a write lock.
Will the call to stopWaiting inside shouldWeWait try to get a WRITE Lock? or simply execute it as it already got the READ Lock initially?
No, it won't try to get write lock.
Container job is done within interceptors, wrapping EJB method calls. For example, when stateless BeanA calls your singleton - it does so through proxy, which makes possible the guarantees given by container (retrieving lock, etc.).
But in this case, it's just a normal method call (stopWaiting), not wrapped by proxy, so no place for magic.
I'm using Guava Eventbus in Vaadin+Spring project and started to have a problem with posting an event from background thread.
Eventbus is instantiated in wrapper class. Objects communicate with the eventbus using static method defined in main UI class to obtain the eventbus object. It is the same way as proposed in Vaadin Dashboard example (DashboardEventBus).
public class MainUI extends UI implements ViewDisplay
{
private EventBusWrapper eventbus_ = new EventBusWrapper();
public static EventBusWrapper GetEventBusWrapper()
{
return ((MainUI) getCurrent()).eventbus_;
}
}
Problem appears in presenter/services classes where I create new thread class and start the thread.
Inside Runnable implemenation of run method I create another object which makes some job.
public class SearchResultsPresenter extends AbstractPresenter<SearchResultView>
{
public SearchResultsPresenter()
{
EventBusWrapper.register(this);
}
#Subscribe
public void UserSearchRequested(Event.UserSearchRequestEvent e)
{
new UpdateContentComponentThread(e.GetSearchElem()).start();
}
#Subscribe
public void UserSearchAppendFoundElement(Event.UserSearchElementFound e)
{
if(e.GetElement().IsValid())
view_.AddElement(e.GetElement());
}
public class UpdateContentComponentThread extends Thread
{
private final Search searcher_;
UpdateContentComponentThread(SearchElement search)
{
searcher_ = new DefaultSearch(search);
}
#Override
public void run()
{
searcher_.Search();
}
}
}
It performs some validation/checking and creates other helper classes.
public class DefaultSearch implements Search
{
private final Scraper scraper_;
...
#Override
public void Search()
{
if(!scraper_.IsConfigured())
return;
...
scraper_.FindElements();
}
}
Then inside scraper's FindElements body I try to post an event using static post method defined in EventBusWrapper.
public class HttpElementScraper extends WebScraper
{
...
#Override
public Collection<Element> FindElements()
{
...
Element elem = ...
Event.UserSearchElementFound e = new Event.UserSearchElementFound(elem);
EventBusWrapper.post(e);
return foundelements;
}
}
At this moment the NullPointerException is thrown and I cannot solve and help myself with the problem.
Exception in thread "Thread-10" java.lang.NullPointerException
at com.project.MainUI.GetEventBusWrapper(MainUI.java:109)
at com.project.events.EventBusWrapper.register(EventBusWrapper.java:24)
at com.project.service.search.scraper.HttpElementScraper.FindElements(HttpElementScraper.java:92)
at com.project.service.search.DefaultSearch.Search(DefaultSearch.java:38)
at com.project.view.search.SearchResultsPresenter$UpdateContentComponentThread.run(SearchResultsPresenter.java:71)
// I ommited not important lines of code and annotations. Most of the components and services connected with them are UIscoped.
Vaadin assumes that access to Vaadin component (and related) instances is synchronized properly. When using the traditional single-threaded request-response cycle to access components it's synchronized automatically.
When using external threads, you need to synchronize code accessing your Vaadin components by using UI.access(). For example:
getUI().access(() -> label.setValue("Hello"));
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.
I've come across this particular scenario many times, and I wonder what's the "clean" way of solving it. It all comes to this: how can I store a reference to an object that's being set in a different Thread?
Let me illustrate this with an example, imagine I have a class named Bar, and objects from this class are retrieved from this method:
public class BarBuilder {
public static void buildNewBar(final BarListener listener) {
// This could be an HTTP request or something that can only be done in a
// different thread
new Thread(new Runnable() {
#Override
public void run() {
listener.onNewBar(new Bar());
}
}).start();
}
}
The important part here is that buildNewBar() method has to be executed in another Thread, so instead of returning the value, it will communicate the result through a listener. This is quite common for operations that need HTTP requests or any sort of connection.
Now, my problem is if I need the value before continuing execution, how can I access to it? I can lock a thread with a semaphore until I have my value, but the storing of the value is what I don't have clear (If I declare a final variable, it cannot be set again). I solved it creating a new class which I named "Pointer", but I wonder why there isn't any built in java class to do this (I used Vector before, but it doesn't seem like a good solution either).
public Bar getBar() {
final Pointer<Bar> barPointer = new Pointer<Bar>();
final Semaphore semaphore = new Semaphore(0);
BarBuilder.buildNewBar(new BarListener() {
#Override
public void onNewBar(Bar bar) {
barPointer.set(bar);
semaphore.release();
}
});
semaphore.acquireUninterruptibly();
// Now I have my value
return barPointer.get();
}
public class Pointer<T> {
T object;
public void set(T object) {
this.object = object;
}
public T get() {
return object;
}
}
Let's see if there is a better way of doing this supported by Java language, I have seen classes like Reference, but it seems like their purpose is something different and setters don't exist (they are read-only), so that doesn't solve my issues either.
public Bar getBar() {
final BarPointer barPointer = new BarPointer().
BarBuilder.buildNewBar(barPointer);
return barPointer.get();
}
public class BarPointer extends FutureTask<Bar> implements BarListener {
#Override
public void onNewBar(Bar bar) {
set(bar);
}
}
In order to eliminate the need to write a custom Pointer class, I would simply use AtomicReference.
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();
//....
}
}