Concurrency/Theread safety in layouts

I feel it must exist but I can’t seem to find any info on whether variables in layouts are thread safe or not.

I’m not talking about ui.access or push in general (I can find lots of info on that).

Requests come into the servlet engine and cause alterations to layouts.

If I use a private member variable in a layout what concurrency model is in effect?

I’ve gathered that vaadin (14) sequences requests to the UI such that only one thread is operating on the UI at a time, be that a click handler or a repaint?

But there’s no guarantee the same thread from the servlet engine is in use each time so layout member variables should be marked volatile?
Or is there some other model in play here?

Thanks

Hi! Every time a request comes to Vaadin Servlet, a Session Lock is obtained (instance of ReentrantLock). All requests including click handlers, repaints, navigation events, data fetching events (Grid, ComboBox etc) are always protected by this lock. The only exception are byte streams when uploading/downloading files, but these exceptions are documented.

Since the UI manipulation code is always triggered by a request going through the Vaadin Servlet, all access to UI fields is therefore protected by one lock. Vaadin emits infrequent asserts on the lock being held, which can help catching unprotected access when running with -ea.

Java Memory Model mandates that actions preceding lock.unlock() happens-before actions successing lock.lock() on that very same lock instance. Therefore, even if a different thread is picked by the Servlet Container (Tomcat, Jetty, other) to handle successive request, the Java Memory Model takes care that all memory effects are synced, and therefore there is no need for you to use volatile or other threading machinery, to enforce thread-safety.

There were attempts to implement a multi-threaded UI, but they all failed since it’s extremely hard to use such UI - generally it’s very easy to get into deadlock. Quoting https://www.researchgate.net/post/User_interface_frameworks_typically_are_single-threaded_Why_is_this_so_and_what_are_the_performance_implications_of_this_single-threading/574f2a5aed99e161083f7294/citation/download :

Attempts to write multi-threaded user interfaces have been plagued by race conditions and deadlock. Deadlock because deadlock of interaction between input event processing and object-oriented modelling of GUI components: actions from the user “bubble-up” from OS to application and application-initiated actions “bubble-down” from application to OS. This tendency for activities to access the same GUI objects in opposite order together with the locks required for thread safety results in inconsistent lock ordering- a recipe for deadlock! There are performance implications of the ubiquitous single event queue model, but safety and liveness considerations trump performance.

Of course you can easily break this Vaadin model, by simply creating a Thread and modifying layout properties from that thread without UI.access() (which obtains the Session Lock properly). However, you should most definitely not do it - there are no benefits in doing this, and you’ll get random ConcurrentModificationExceptions in production which are almost impossible to reproduce and fix.

Vaadin gives the illusion of a single UI thread similar to what you have in e.g. Swing. You don’t need to use constructs such as volatile or synchronized in component implementations unless you’re also interacting with them directly from custom worker threads.

Like you observed, there isn’t a single thread because of the way the servlet container dispatches requests on multiple threads. Instead, the internal request handling part of Vaadin uses a ReentrantLock per HTTP session to ensure that multiple requests from the same user are handled sequentially with the same happens-before relationships that you would expect from a single thread.

The UI.access method is technically a helper API for interacting with that same lock instance. In addition, the method also schedules tasks for later to avoid potential deadlocks if the lock is currently held by another thread.

Interesting,and many thanks guys.