0

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.

Vishrant
  • 15,456
  • 11
  • 71
  • 120
  • youre looking for https://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html . But use it with care, it can easily cause memory leaks if not done properly – Felix Mar 09 '21 at 18:07
  • @codeflush.dev could you please elaborate on the memory leak part, what issues it could create? Also, could you please add an example of `ThreadLocal`? – Vishrant Mar 09 '21 at 18:11

1 Answers1

1

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

Felix
  • 2,256
  • 2
  • 15
  • 35
  • Thanks for adding the example, do you know why do we have to keep track of last operation while writing to `ThreadLocal`? This is `LogbackMDC` `put` implementation https://github.com/qos-ch/logback/blob/61ffd3aba042bbb22f588599ff5574d3b9667d22/logback-classic/src/main/java/ch/qos/logback/classic/util/LogbackMDCAdapter.java#L105 – Vishrant Mar 09 '21 at 18:52
  • This is highly specific to the Logback use-case. See the comment and the linked Tickets in the class you shared. – Felix Mar 09 '21 at 21:58