Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cu-dev] Correct context save for ManagedThreadFactory

Hello everybody,

I have an issue, what is the expected behavior of ManagedThreadFactory, particularly when the calling thread's context should be saved; my expectation was that it is similar to ManagedExecutorService. I did PR and got answer from Nathan, that it should happen on JNDI lookup():

https://github.com/jakartaee/concurrency/pull/212


The javadoc for ManagedThreadFactorysays this:

https://github.com/jakartaee/concurrency/blob/1acd0022c9955f2a6c7da5604ac9b0e09712fd31/api/src/main/java/jakarta/enterprise/concurrent/ManagedThreadFactory.java#L40

* {@link ThreadFactory#newThread(Runnable)} method
* will run with the application component context of the component instance
* that created (looked-up) this ManagedThreadFactory instance.<p>
* The Runnable task that is allocated to the new thread using the

I understand it this way -- when executed, the java:comp is set to the EJB doing the JNDI lookup.

But saving thread context at this moment is strange to me. Looking up in JNDI simply returns the object, not initializing it.

I have two questions, when it is expected to save the calling thread:


1)

@Stateless class A {

    @Resource("java:app/concurrent/MTF1") private ManagedThreadFactory mtf1;

    public void f() {

        mtf1.newThread(() -> {}).start();

    }

}

Here, the mtf1 field is initiated during creation of the EJB object A, which is definitely wrong thread for context save.


2)

@Stateless class B {

    public void f1() {

        ManagedThreadFactory mtf = InitialContext.doLookup("java:app/concurrent/mtf1");

        mtf.newThread(() -> {}).start();

    }

    public void f2() {

        ManagedThreadFactory mtf = InitialContext.doLookup("java:app/concurrent/mtf1");

        mtf.newThread(() -> {}).start();

    }

    public void f3() {

        ManagedThreadFactory mtf = InitialContext.doLookup("java:app/concurrent/mtf1");

        mtf.newThread(() -> {}).start();

    }

}

All 3 methods return the same object. If they have to store the context after doLookup(), they would need to store it in ThreadLocal - correct? Also, the factories must be notified, that they were looked-up, right?


The easiest explanation seems to me to be most obvious behavior -- save the context during newThread and stored in the ManagedThread. It is consistent across all usages (lookup, even in multiple invocations, injection) and also consistent with ManagedExecutorService.

The same is with ForkJoinPool using ManagedThreadFactory, but let's solve ManagedThreadFactory itself first.

Thank you for your opinion or explanation, where I'm doing a mistake.

Petr



Back to the top