Is MVC in Swing Thread Safe

Is MVC in Swing Thread Safe

This is too long for a comment...

First and this is unrelated to the rest of this answer: there are many different MVCs out there and the one you used in that piece of code you posted here is not the same as the one used in the article you linked to: http://www.oracle.com/technetwork/articles/javase/mvc-136693.html

The article correctly points out that it's just "A common MVC implementation" (one where the view registers a listener listening to model changes). Your implementation is a different type of MVC, where the controller registers a listener listening to model changes and then updates the view.

Not that there's anything wrong with that: there are a lot of different types of MVCs out there (*).

(Another little caveat... Your view is aware of your controller in your example, which is a bit weird: there are other ways to do what you're doing without needing to "feed" the controller to the view like you do with your setControl(...) inside your MVCView.)

But anyway... You're basically nearly always modifying the GUI from outside the EDT (which you shouldn't be doing):

public void setIconLabel(final Icon icon) {
myLabel.setIcon(icon);
}

You can check it by adding this:

System.out.println("Are we on the EDT? " + SwingUtilities.isEventDispatchThread());

This is because you're eventually doing these updates from your SwingWorker thread (the SwingWorker thread is run outside the EDT: it's basically the point of a Swing worker).

I'd rather update the GUI from the EDT, doing something like this:

public void setIconLabel(final Icon icon) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
myLabel.setIcon(icon);
}
});
}

Is the Swing repaint() method still safe to use outside the EDT in Java 7+?

This is the official reference:

Swing's Threading Policy

In general Swing is not thread safe. All Swing components and related classes, unless otherwise documented, must be accessed on the event dispatching thread.

And the repaint method does not "document otherwise".

To doubly reassure you that you do not need to look any further than an individual method's Javadoc for the definitive answer, see for example how a method's thread safety was documented in Java 6 Javadoc.

Update

Apparently, more clarification is needed as to the distinction between normative specification, descriptive technical articles, and details of any specific implementation. What the Javadoc states is this: there is no guarantee that repaint is a thread-safe method. Incidentally, the often-discussed decision in Java 7 to remove the "thread-safe" designation from most of the Swing API was just that: a change in contract, not implementation.

The specific implementation of repaint in OpenJDK 7 appears to be thread-safe, a fact which has nothing to do with guarantees given by the specification. Code which relies on the thread safety of repaint or other methods is broken and is not guaranteed to behave properly on all Java implementations.

does swing view needs synchronized methods if its set by new threads in controller

Anything in swing has to run on the EventQueue. If you have a method called from swing it will already be running there (as in an Action listener). If you don't know if you're on the event queue, EventQueue.isDispatchThread() will tell you. When you know you're not, reference a swing class or method using EventQueue.invokeLater() or invokeAndWait if you need to see results. (This must be done from the main method.)

Be very careful about this; you have to check your code. If not, my experience is that the swing UI will be just a little bit flakey, with the occasional unreproducable oddity. There's no easy way around eyeballing each line of code.

Actually, there is. Do everything on the EventQueue, then you won't have to worry. You're probably not doing a whole lot of work outside swing anyway. If you are, it's probably worth the loss of speed to avoid multithreading problems. If your non-swing work is extensive but simple, use the SwingWorker class. It gives you an extra thread under highly controlled conditions and should save you a lot of grief.

Your classes (View and Controller) are independent of threads, and should work just fine all running in one thread. Don't confuse classes and threads. (I'll admit, I'd be tempted to have the Controller firing off threads in all directions, but you have to be prepared to be very careful and know everything there is to know about multithreading.)

If you do multithread, the EventQueue can be a bit handy because you don't have to protect fields referenced only there--it's an island of single threading in a dangerous sea. On the other hand, don't do any synchronization there; you'll block your UI. You can launch threads from there and you may have to just to avoid blocking. (Once you start multithreading, it's hard to stop.)

If Swing models' getters aren't thread-safe, how do you handle them?

  1. No, not wrong, but as with any cross-thread communication you need to ensure you provide appropriate thread-safety mechanisms if you decide to do this (e.g. use of synchronized or volatile). For example I typically write my own TableModel implementations, typically sitting on List<X> where X is my business object. If I intend for other threads to query the List I will make this a synchronized Collection. It's also worth noting I would never normally update the List from other threads; only query it.
  2. Because it's exactly the same situation as with any other multi-threaded application.
  3. I typically make the collection synchronized (see 1).

Caveat

Despite my answer above I typically do not access models directly outside of the EDT. As Carl mentions, if the action of performing an update is invoked via some GUI action there's no need to perform any synchronization as the code is already being run by the EDT. However, if I wish to perform some background processing that will lead to the model being changed I will typically invoke a SwingWorker and then assign the results of doInBackground() from within the done() method (i.e. on the EDT). This is cleaner IMHO as the doInBackground() method has no side-effects.

How to implement SwingWorker in multithreaded Swing MVC client-server program?

Usually a SwingWorker should not be necessary in your Code, if you do all time consuming tasks in some daemon threads of you Controller.

For me your problem descriptions sounds like you are doing some major work in the context of the EDT. First thing to check would be in my eyes, the program parts that you run via invokeLater.

If you are starting, maybe a lazy evaluation, as you are already in the EDT, the exact same behavior as you described it in this thread would occur.

Spring MVC 3 for @Autowired Singleton Thread-Safety

Here Thread Safety depends upon the internal locking of userService in case of scope singleton

This is what ultimately happens => The same userSpace bean is used for both the requests and both requests concurrently access userService bean. So the IUserService needs to be thread safe for the whole operation to perform well.

Or

put the scope to request.

In which case a new bean is allocated for every request and the whole operation is thread-safe, thanks to thread confinement. Provided you code accordingly in IUserSpace

Java MVC Where/When to get my view on EDT and how my controller do actions on EDT?

Anything that interacts or can change the UI in anyway MUST do so from within the context of the Event Dispatching Thread.

Swing, by design, is not thread safe. That is, there are no checks in the default libraries to make determinations about what thread the various models and components are been executed on, it is assumed the developer will already have made these determinations.

So question1- When is the best time to put my Gui on edt.When i create View?

Immediately. You have no way of knowing when a component may become realised (displayed on the screen and/or attached to a native peer)

question 2- Do i have to do updates from my controller like this?Each time? -

No, in fact, I'd be very worried if I found myself coding like this all time. Make the determination that the models and components MUST be executed within the context of the EDT and make whatever is interacting with these models and components meet these requirements.

This would mean, if you are loading data from a separate Thread, you would need to ensure that any time they update the model, they are synchronizing these updates to the EDT to ensure that if the model notifies the UI, it all occurs within the context of the EDT.

Don't make assumptions about the state of the model, statements like "I know..." will come back to haunt you, especially when some one else makes use of your API.

Unless you physically create the model yourself (outside the EDT) and guarantee it's isolation while it's being loaded, don't assume anything that is given to you isn't attached to the UI in some way.

An easier solution is to use a SwingWorker when you want to perform operations off the EDT, as it provides this synchronisation via it's publish/process/done methods

The MVC pattern and Swing

A book I'd highly recommend to you for MVC in swing would be "Head First Design Patterns" by Freeman and Freeman. They have a highly comprehensive explanation of MVC.

Brief Summary

  1. You're the user--you interact with the view. The view is your window to the model. When you do something to the view (like click the
    Play button) then the view tells the controller what you did. It's the
    controller's job to handle that.

  2. The controller asks the model to change its state. The controller takes your actions and interprets them. If you click on a
    button, it's the controller's job to figure out what that means and
    how the model should be manipulated based on that action.

  3. The controller may also ask the view to change. When the controller receives an action from the view, it may need to tell the
    view to change as a result. For example, the controller could enable
    or disable certain buttons or menu items in the interface.

  4. The model notifies the view when its state has changed. When something changes in the model, based either on some action you took
    (like clicking a button) or some other internal change (like the next
    song in the playlist has started), the model notifies the view that
    its state has changed.

  5. The view asks the model for state. The view gets the state it displays directly from the model. For instance, when the model
    notifies the view that a new song has started playing, the view
    requests the song name from the model and displays it. The view might
    also ask the model for state as the result of the controller
    requesting some change in the view.

Sample Image
Source (In case you're wondering what a "creamy controller" is, think of an Oreo cookie, with the controller being the creamy center, the view being the top biscuit and the model being the bottom biscuit.)

Um, in case you're interested, you could download a fairly entertaining song about the MVC pattern from here!

One issue you may face with Swing programming involves amalgamating the SwingWorker and EventDispatch thread with the MVC pattern. Depending on your program, your view or controller might have to extend the SwingWorker and override the doInBackground() method where resource intensive logic is placed. This can be easily fused with the typical MVC pattern, and is typical of Swing applications.

EDIT #1:

Additionally, it is important to consider MVC as a sort of composite of various patterns. For example, your model could be implemented using the Observer pattern (requiring the View to be registered as an observer to the model) while your controller might use the Strategy pattern.

EDIT #2:

I would additionally like to answer specifically your question. You should display your table buttons, etc in the View, which would obviously implement an ActionListener. In your actionPerformed() method, you detect the event and send it to a related method in the controller (remember- the view holds a reference to the controller). So when a button is clicked, the event is detected by the view, sent to the controller's method, the controller might directly ask the view to disable the button or something. Next, the controller will interact with and modify the model (which will mostly have getter and setter methods, and some other ones to register and notify observers and so on). As soon as the model is modified, it will call an update on registered observers (this will be the view in your case). Hence, the view will now update itself.

What is the (event-dispatch) thread safe usage for JOptionPane.showMessageDialog and swing.utils.invokeAndWait?

Take a look at groovy.swing.SwingBuilder, it encapsulates invokeAndWait and invokeLater. Your example can be written as:

import groovy.swing.SwingBuilder
import javax.swing.*
import java.awt.*

def swing = new SwingBuilder()
def myMainFrame = new Frame()

swing.edt {
JOptionPane.showMessageDialog(
myMainFrame, "Hello There");
}

How to Start a Java MVC Application With a Swing GUI

All the code that creates or interacts with Swing components must run on the event dispatch thread. So the second form of your code, that is the bellow code is correct.

`SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Model model = new Model();
View view = new View(model);
new Controller(model, view);
}
});`

The reason for all UI code that must run through EDT or worker thread is to avoid Multithreaded problem. You may see many swing programs may not init code in EDT. This is perfectly ok. But when your swing gets complecated, then there is probability for error. my self in simple swing apps lanching from main thread, i did not face dead locks are race conditions. Quick tasks uses EDT and long running tasks uses worker threads.
Here is link on multithreaded problem on ui

Please let me know if i went wrong



Related Topics



Leave a reply



Submit