0

I want to ask a question about synch. of gui thread and another thread that reads component's state periodically, say label in Java. Here is the case, I have gui and a thread. And I have a label in gui. I have a thread that periodically (say 100ms) reads that label. I think there occurs a problem when gui changes the label and at the same time thread attempts to read label (concurrentModificationException error). How can I overcome this situtaion?

canromero
  • 99
  • 3
  • 12
  • Looking at the source of JLabel, `JLabel.getText()` can't send a `ConcurrentModificationException`. Are you sure you are setting the text of the JLabel in the EDT? Can you show the relevant code? – assylias Apr 03 '12 at 09:38
  • I use invokeLater and invokeAndWait methods to change state of component but this is not the problem case. The problem is when I changed the label from gui. (ok. label is not a good example then say combobox). The point is when I changed the gui component from the user interface and periodic thread can read the component state at the same time then both EDT and my thread uses the same combobox. to be more specific EDT changes the state of the combobox and my thread reads the combobox at exactly the same time. – canromero Apr 03 '12 at 10:29
  • you should post the relevant part of your code, as well as the stack trace you get with the Exception and the line that throws it. – assylias Apr 03 '12 at 10:34
  • ConcurrentModificationException is typically thrown when you try to remove items from a collection in a for loop for example, in which case it has nothing to do with the GUI or multithreading. Post your code if you want specific and relevant answers. – assylias Apr 03 '12 at 10:37

1 Answers1

4

Unless explicitly otherwise stated in the Javadocs, Swing components (assuming you're talking about Swing) are not thread-safe. They can only be manipulated by the Event Dispatch Thread (EDT).

If you want to manipulate Swing components from another thread, there are several ways you can do it, including SwingUtilities.invokeLater(), SwingUtilities.invokeAndWait(), and SwingWorker (these don't actually manipulate the components from another thread - they just make it easy to coordinate with the EDT).

SwingUtilities.invokeLater() and invokeAndWait() allow you to pass a Runnable to them, and have the Event Dispatch Thread run them for you. The SwingWorker allows you to create a task and divide it into two portions: a portion that is long running and shouldn't be run in the EDT, and a portion with the work to do in the EDT once the background job is complete.

Here's a tutorial on concurrency with Swing. It has all you need to learn about using SwingUtilities and SwingWorker.

Note, however, that Swing components don't do anything to detect (erroneous) multi-threaded access. Swing components don't throw ConcurrentModificationExceptions. If you're getting that, you're either using a Windowing toolkit other than Swing, or it exception is being raised by some other code. (If you're using SWT, have a look at this).

Community
  • 1
  • 1
Greg Kopff
  • 15,945
  • 12
  • 55
  • 78
  • I used invokeLater and invokeAndWait methods when I update the state of label's text. If there is no ConcurrentModificationExceptions in getLabel then what happens when gui changes the label's text and at the same time other periodic thread attempts to read label's text. (It seems both Event Dispatch Thread and my Thread enters the critical section same time.) – canromero Apr 03 '12 at 10:09
  • Here's the source code for [`JLabel.getText()`](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/javax/swing/JLabel.java#JLabel.getText%28%29). Swing isn't thread safe, and so nothing prevents multiple threads from accessing the components, but you'll won't get the variable visibility guarantees that the Java Memory Model provides. – Greg Kopff Apr 03 '12 at 10:46
  • Are you *actually* experiencing ConcurrentModificationExceptions? Or are you just wondering about whether your code is thread-safe? – Greg Kopff Apr 03 '12 at 10:48
  • You need to *read* the label's text from the EDT too - and then there are no race conditions possible (as everything is run from the EDT - either your update code will be running, or your read code will be running - but they can't collide). – Greg Kopff Apr 03 '12 at 10:52
  • I haven't got any exceptions yet, I just wonder what happens if this case is happened. I need to be sure component updates and reads are thread-safe. So I need to learn how to read component's state from EDT. – canromero Apr 03 '12 at 10:57
  • 2
    Okay - finally then, have you considered using *listeners* to receive updates from the GUI, rather than polling the GUI from another thread? – Greg Kopff Apr 03 '12 at 11:03