1

So I'm in a situation where I need to write an intensive operation for part of my company's application, keep it off of the UI thread (we use Swing), and interact with a whole bunch of highly thread-unsafe components. Fun times.

I'm trying to simplify this for myself. So here's how it would go:

1) The data from the thread-unsafe components would only be read, not written to.

2) A reference to that data would be passed to the background thread as shown below:

final Object someData = getSomeData();
        Runnable task = new Runnable() {
            @Override
            public void run() {
                doSomething(someData);
            }
        };

Also, a modal dialog would block the user from inadvertently changing any of the values during this process. So the state of someData would be unchanged during the entire process, it would just be read from.

So, I'm always very paranoid about memory consistency issues. Would there be any here? By passing the reference in this way, would the background thread get the most up-to-date status of it at that point?

Thanks.

craigmiller160
  • 5,751
  • 9
  • 41
  • 75
  • A reference won't go stale if that's what you mean. Every time you work with it, it will reflect the current state. – ChiefTwoPencils Mar 22 '16 at 20:52
  • I would clone the someData before passing it to a thread. When the thread has finished doing something with that data you can pass the outcome back to the UI. – Heri Mar 22 '16 at 21:05
  • Inner classes don't really have anything to do with it. The issue is the second thread, and it demands the usual thread-safety precautions: `synchronized` or `volatile`. – user207421 Mar 22 '16 at 22:33
  • I know that, but properly synchronizing this object is virtually impossible. Just imagine the most screwed up batch of spaghetti code imaginable. I can ensure that no writes are done to someData during this process, but if I pass it to that background thread in the manner demonstrated above, will I be able to properly read its current state? – craigmiller160 Mar 23 '16 at 13:13

1 Answers1

2

If you are starting a new thread using the Runnable, or submitting it to a Executor, then the new thread will see all the actions that happened up to the creation of the thread. So as long as the state doesn't change while the background thread is running, then your data will be visible. This will be easier to guarantee with immutable objects.

Executor:

Memory consistency effects: Actions in a thread prior to submitting a Runnable object to an Executor happen-before its execution begins, perhaps in another thread.

Thread.start:

When a statement invokes Thread.start, every statement that has a happens-before relationship with that statement also has a happens-before relationship with every statement executed by the new thread. The effects of the code that led up to the creation of the new thread are visible to the new thread.

For sending data back to the UI thread, then you have visibility guarantees if the changes go through invokeLater. See Is happens-before relation given in case of invokeLater() or invokeAndWait?

Some of this is managed for you if you use a Swing Worker. This allows you to override a method to run in the background thread, and then another to run in the event dispatch thread once it's finished.

Community
  • 1
  • 1
fgb
  • 18,439
  • 2
  • 38
  • 52
  • Thank you so much. This is exactly the answer I was looking for. Through the use of modal dialogs (with the ability to close them turned off), I can prevent any changes from being made to the application state during this process. It's not the most elegant solution, but until my company gets to doing a full code rewrite it's the best option I have. – craigmiller160 Mar 24 '16 at 19:29