getApplication vs ThreadLocal instance (Shiro related)

I’ve made a test about obtaining the application reference:

long start = System.currentTimeMillis();
				for (int i = 0; i < 1000000; i++) {
					((MyApplication) getApplication()).test();
				}
				System.out.println(System.currentTimeMillis() - start);

				start = System.currentTimeMillis();
				for (int i = 0; i < 1000000; i++) {
					MyApplication.getInstance().test();
				}
				System.out.println(System.currentTimeMillis() - start);

The numbers are in:
1455ms
1548ms

((MyApplication) getApplication()).test(); // being on top

But that’s not all, I’ve picked from integrating Shiro with Vaadin somewhere that I should do this, which also adds overhead I didn’t account for:


@Override
	public void transactionEnd(Application application, Object transactionData) {
		if (application == MyApplication.this) {
			// used by Shiro
			MyApplication.currentApplication.set(null);
			MyApplication.currentApplication.remove();
		}
	}

@Override
	public void transactionStart(Application application, Object transactionData) {
		if (application == MyApplication.this) {
			MyApplication.currentApplication.set(this);
		}
	}

My conclusion is that there’s no reason to use a ThreadLocal when it comes to the application instance.
This came up when I was thinking how to move around references between distant objects in my UI hierarchy.
One way is keeping them in a ThreadLocal data structure, but if you can access the application instance why use a ThreadLocal?
I can keep the reference data structure in the application and call getApplication from my components

Also I’ve seen a comment
HERE
that fields in the Application gets stored in the session. It’s not true, put this in your application init() and add some random fields to you application to be initialized before this runs:

HttpSession httpSession = ((WebApplicationContext) getContext())
				.getHttpSession();
		Enumeration attributes = httpSession.getAttributeNames();
		System.out.println("attributes");
		while (attributes.hasMoreElements())
			System.out.println(attributes.nextElement().toString());
		String[] values = httpSession.getValueNames();
		System.out.println("values");
		for (String s : values)
			System.out.println(s);

There’s only the WebApplicationContext in there.

False:

One problem is that in the constructor of a component getApplication() returns null because the component is not yet attached to an application.

Yes, I’ve met with this yesterday, it can be done in an override of attach() as in the answer
HERE

My use case example:

I’m having a split panel on which I put another split panel in the second component:

public MainSplitPanel() {
...
setSecondComponent(filtersSplitPanel);
}

now I’ve just added the following, and I can access it from another branch to put something on it, in my case react to a button click from the header section while the targeted component is in the content

@Override
	public void attach() {
		super.attach();
		((ReallotoApplication) getApplication()).uiRefChache[RefCache.FILTERS_SPLIT_PANEL]
 = getSecondComponent();
	}

Yes, there is many ways to do that. I would use ThreadLocal or just pass Application instance as a constructor parameter instead of that attach() way. With ThreadLocal the ((ReallotoApplication) getApplication()) cast can be avoided too.

Did you bother looking in the web app context object? If so, you’ll see that the app state is stored there. It’s a fundamental part of the Vaadin architecture:


https://vaadin.com/book/-/page/architecture.server-side.html

Try changing your example to actually inspect the object, and you’ll see an instance of your application in there:

        HttpSession httpSession = ((WebApplicationContext) getContext()).getHttpSession();
        // redundant, but just to show this is coming from the session
        WebApplicationContext wac = (WebApplicationContext) httpSession.getAttribute(
            "com.vaadin.terminal.gwt.server.WebApplicationContext");
        for (Application a : wac.getApplications()) {
            System.out.println(a.getTheme()); // just an example
            MainUI mainApp = (MainUI) a; // cast to my actual app
            System.out.println(mainApp.getUserService().toString()); // call any getter
        }

I can see any of the fields of my application object in there.

Cheers,
Bobby

There’s a hitch with

((MyApplication) getApplication()).test();

in the way attach() gets called by the component tree build up, meaning that it’s called from the innermost child outwards to outmost parent, in that order.
Naturally, I needed to pass the instance from the innermost child, but I had the instance… instantiated in one of the parents. I decided to pass the reference to the MyApplication entry instead and get the reference from the reference cache there

On the other hand, as far as I see, a thread local get() searches through a map, so, the more thread local variables you have, the lenghtier the search will be (haven’t done any statistics yet)

Map lookups in a properly implemented hash map (auto-expanding at correct times with hysteresis to avoid unnecessary resizes etc.) are almost unaffected by the number of items in the map as long as the hash codes of the objects being looked up are properly spread. Most lookups are effectively fixed time, and for some you need to go through a list of a few elements.

ThreadLocalMap looks quite well designed to me and is specifically optimized for this use. In the beginning, it will take a little time for expanding the initial map size and rehashing if there are many new registrations, and cleaning the map when removing entries can take a little work, but even that is using quite effective heuristics for partial cleanup etc. Also the hash code mechanism of ThreadLocal has been designed specifically for this use to avoid hash collisions. Once the size of the map roughly stabilizes, also insertions and deletions should be quite fast.

Of course, a bad implementation of the hashCode() method can make a hash map perform worse than a simple list, but that is not the case for ThreadLocal, nor for most Java library classes apart from the class URL which you should never use as a map key for several reasons.

Good insight. I’ve decided on the threadlocal, mostly because Shiro also requires it and I don’t want to complicate thing at the moment (itisn’t trivial to breakpoint into the threadlocal and see what’s in the map th
Otherwise, I seriously doubt there’s a b-tree behind the scenes helping with that map numeric keys performance… but I don’t know…

google also gives good info on this searching with:
“java 6 threadlocal performance”
“java threadlocal best practice”

also for optimisation this one is probably useful:
google: “java debug threadlocal” finds
THIS

Actually I can’t access the components using a static threadlocal variable, because I couldn’t set it with an initial value of the current instance at any time, and work with that (comes out null when I get() it, except if it’s initialized on each request

Possible explanation:

  1. threads and instances aren’t bound together between requests, although there’s a session and a thread pool, and intuitively you would think that while a session is alive, the same thread is bound to the same instance. I think now that it’s as the servlet specification sais, on each request a new instance of a request is build, and probably the old values copied over,
    resulting in another instance representing the old values, bound to a new thread

So there isn’t really a “vs” in there as the title suggests :grin:
Each case has its use

Not sure if I understood the issue correctly, but one should note that servers use a pool of threads that get reallocated for different requests and sessions. Therefore, e.g. ThreadLocal can only be used effectively within a request - set at the beginning e.g. in a transaction listener or an HTTP request listener and cleared at the end of the request with a corresponding listener.

Yea, that’s the truth. I intuitively thought there would be an implementation doing this automagically, following this idea:

If there’s the same instance in the session servicing the same requests for that session, it probably would’ve been useful to cache the thread local cache along with it, so,
when a request is about to start a thread and be passed to a respective application instance, the thread is populated with the old cache. Don’t know if this would’ve been an improvement. It is certain that some improvements could’ve appeared, such as threads that return to the pool aren’t reset, so if they don’t get used, by keeping a reference of that thread with the instance in session, the requests would ask by session id to be resolved by the same instance, with the same thread (not needing to refill the thread cache), thus gaining some CPU cycles). The logic wouldn’t have had to be difficult: get the instance for that request with that session id, if the reference to the old thread is null, get a new one from the pool, if not, get the old one populated. The thread pool implementation would have itself to keep a reference to the application object, and clean up a thread when its allocated to a new instance. Perhaps have some sort of mediator between the session and the thread pool

Instead, we are using TransactionEnd and TransactionStart to populate the “new” (void of local cached variables) thread’s local variables each request ourselves.