Reputation: 999
I have a small program presenting the user with a GUI to select a file, the program then executes based on the files contents and presents the results accordingly.
This is the loop running in the main thread (the main()
method):
do {
args = fg.getFile();
} while (!fg.started);
fg.started
is a boolean variable set to true when the user has selected a file and presses the "start" button.
However, this does not work UNLESS I put a random task inside the loop:
do {
args = fg.getFile();
System.out.println("");
} while (!fg.started);
This works.
Can anyone explain to me why this is?
I'm aware of a solution involving the Thread class, with notify()
and wait()
etc, but now I'm just curious about this.
Upvotes: 0
Views: 318
Reputation: 116918
fg.started is a boolean variable set to true when the user has selected a file and presses the "start" button.
However, this does not work UNLESS I put a random task inside the loop:
That's because two threads are accessing the started
field without memory synchronization. You don't show the definition of fg.started
but I suspect that you need to make sure that it is volatile
. You also might consider switching to an AtomicBoolean
. Here's the Java tutorial about memory synchronization.
volatile boolean started;
The issue with multi-threaded applications is that parts of your program can run in different processors with their own local memory cache. Whenever threads modify or access shared fields there needs to be explicit synchronization to ensure that they aren't just looking at the local cached value of the field.
It is working when you add a System.out.println(...)
because the PrintStream
's methods are synchronized so you are adding indirect memory synchronization.
making getFile() synchronized fixed it, thanks. Care to explain why? :)
Because, like the System.out.println(...)
you are adding indirect synchronization.
Upvotes: 2
Reputation: 8386
You should syncronize the access of fg
otherwise this may happen:
fg
, and then get paused.fg
and get's deactivated immediately.fg
, then pause.fg
is locked again! If you need help/instructions on concurrency/parallel execution, see Oracle - Syncronization for information.
Upvotes: 2