I'm learning Java multithreading programming by the book "Java Concurrency In Practice". In chapter 9.4.2 Split Data Model, I read this:

From the perspective of the GUI, the Swing table model classes like TableModel and treeModel are the official repository for data to be displayed. However, these model objects are often themselves "views" of other objects managed by the application. A program that has both a presentation‐domain and an application domain data model is said to have a split‐model design (Fowler, 2005).

In a split‐model design, the presentation model is confined to the event thread and the other model, the shared model, is thread‐safe and may be accessed by both the event thread and application threads. The presentation model registers listeners with the shared model so it can be notified of updates. The presentation model can then be updated from the shared model by embedding a snapshot of the relevant state in the update message or by having the presentation model retrieve the data directly from the shared model when it receives an update event.

The snapshot approach is simple, but has limitations. It works well when the data model is small, updates are not too frequent, and the structure of the two models is similar. If the data model is large or updates are very frequent, or if one or both sides of the split contain information that is not visible to the other side, it can be more efficient to send incremental updates instead of entire snapshots. This approach has the effect of serializing updates on the shared model and recreating them in the event thread against the presentation model. Another advantage of incremental updates is that finer‐grained information about what changed can improve the perceived quality of the display if only one vehicle moves, we don't have to repaint the entire display, just the affected regions.

What is the meaning of "Split Data Model"? Can you show me an example to help me understand it?


The presentation domain data model is concerned with rendering the application domain data model on the screen. For example, let's say you have a table in your application data model, and want to present that data, filtered and/or sorted as the user chooses. In that case, the choice of filter and/or sort is an aspect of the presentation domain. (The filter/sort can be represented as data and persisted, even, should the user want to retrieve that same view.)

By separating the concerns of presentation model from application model, it is easy for us to create an application that can have multiple simultaneous views (presentations) of the same application data. Imagine one user having multiple windows open looking at the same application data, though probably presented somewhat differently (in our example, maybe sorted or filtered differently).

Now, also imagine two or more users looking at the same data (possibly with different filter/sort). Once we have multiple users potentially altering the same data (via their individual presentations), we need to apply multi-threaded coordination (transactions, locks, or other) over the application model.

By contrast, the presentation model won't need threading coordination (unless you persist views and allow multiple users to edit them).


The idea here is to incrementally change things using events instead of refreshing the model every time the user needs the "latest data".

Suppose for example an application that shows the contents of a database table, for example, in a select box. Usually, when you refresh the component, the app queries the whole database table and update the whole list, even if 90% of the list has the very same elements.

Now suppose a second situation. You have a table of alarms for different components. Instead of polling all of them periodically, you wait each one of them to notify you when something happens. So you're actually listening for events instead of asking them all every time "is that ok? is that ok?"

An example is OSGI. Eclipse for example uses OSGI (Equinox) to manage its modules and plug-ins (in fact, Eclipse itself is a big plug-in manager). When you update a module or install a new plug-in, you don't have to restart the whole application to load the changes. Instead, Eclipse is notified by the OSGI engine and reloads just that part that was updated, via an event. So changes are updated incrementally and, in most of the cases, without the need of re-starting the app.

  • thank you for your answer,are you meaning Split means incrementally,and how to understand the example TableModel and TreeModel,why authors say they are Split Model?
    – FireSun
    Jan 14 '16 at 13:30

Consider software that controls a complex instrument. Periodically it polls the instrument to read a bunch of values: voltages, pressures, percent complete, warning flags, etc. Imagine that the data comes down as XML/JSON, or maybe some binary form, over USB or Ethernet. This data is displayed in a modeless dialog for the user to monitor. That dialog may be a two way interaction, i.e. is has an "Abort" button. In Java, you would probably have a Thread doing this polling, then parsing the data. Many other languages would do similar.

Then, where to put the data, and how?

Somewhere deep inside that Dialog is a Panel inside a Panel that contains a Slider or Button or TextField to show these results. Is it at all reasonable that this deeply buried data is THE model, the official true repository of the official true status of the instrument? For example, if the voltage gets too high and you want to pop up an alert or send an email, should that code need to look through the nested JPanels? No.

Is it reasonable for your Polling Thread to even know how to find the buttons within that Dialog? Should it know to do (very hand waving over bad code) getComponent(EAST).getComponent(3).getStatusTextField().setText("4.56 pounds"); Almost certainly not. If you are following Law of Demeter, that might become a bit simpler, getEscapeModuleForCapsule3StatusTextField(). But even that creates a ton of linkage between the Thread and the GUI. What if you also want to have an Android and an HTML5 version of your code? What if Marketing changes some of the widgets to Sliders or Spinners? How about a European version using kilograms? What if that voltage field is really 3 similar fields on three different JPanels, two are Text and one a Spinner?

O.K., I admit that I am exaggerating the previous two issues a bit.

Most importantly, which is the main reason this topic came up in JCiP, even if you work around all these problems and design issues so that the polling Thread can get to the relevant widgets, it's a pain in the butt to modify the value, because Swing is single threaded. All the calls coming from the polling Thread are on the wrong thread and have to be wrapped in awkward SwingUtilities.invokeLater(new Runnable() { public void run() {// real code here } });

Shared Data Model

In a "Shared Data Model", you are free to do things in an arguably much more natural way. You define an InstrumentModel class, one that makes sense to your company and instrument, with relevant setters, getters, and, oh yeah, bounds checks. It could fire special events when that voltage gets too high. This model will make a lot more sense to your internal scientists and engineeers than many levels of nested JPanels. This model must be made to be thread safe.

Note that this model has no knowledge of whether it will be Swing, GWT, HTML5 or American Sign Language that will be the output. That's Decoupling. The Polling Thread puts the data into the InstruementModel. It (or something) then fires an event to the GUI - in the simplest form, theHugeDialog.repaint(); Note that in Swing these repaint requests are queued, so, hopefully, your dialog doesn't repaint 100s of times per change.

The GUI, in paintComponent() or similar (there are a few gotchas), then pulls data from the InstrumentModel. It is automatically running on the proper Swing AWT Thread, so no need for invokeLaters(). Since you cleverly made the InstrumentModel thread safe, reading data doesn't clash with the PollingThread writing data. If there is also a VeryImportantVoltage text field on the main application window, it can update too from the InstrumentModel.

This is the "snapshot" update - basically, you redraw the entire GUI. If the GUI is huge and you are updating 100s of times a second, this may be too slow. Then you go to an incremental update where only the changed data is updated. This gets very complicated very quickly.

This site is temporarily in read only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .