Reputation: 2979
Consider this program:
public class Test {
private int i = 1;
public void f() {
Runnable runnable = new Runnable() {
@Override
public void run() {
if (i != 2)
throw new AssertionError("i != 2");
}
};
i = 2;
new Thread(runnable).start();
}
}
According to the Java Memory Model, in run()
, i
is guaranteed to be equal to 2, at least because:
A call to
start()
on a thread happens-before any actions in the started thread.
So i = 2
happens-before if (i != 2)
. So far, so good.
But what if we don't start any thread after the assignment:
public class Test {
private static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();
private int i = 1;
public void f() {
Runnable runnable = new Runnable() {
@Override
public void run() {
if (i != 2)
throw new AssertionError("i != 2");
}
};
i = 2;
EXECUTOR.execute(runnable);
}
}
The previous rule does not apply. What guarantees that i = 2
happens-before the execution of run()
in that case?
Does assigning the variable before creating the Runnable
have any affect on the happens-before order:
public class Test {
private static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();
private int i = 1;
public void f() {
i = 2;
EXECUTOR.execute(new Runnable() {
@Override
public void run() {
if (i != 2)
throw new AssertionError("i != 2");
}
});
}
}
?
Upvotes: 1
Views: 72
Reputation: 198211
From the ExecutorService
Javadoc:
Actions in a thread prior to the submission of a Runnable or Callable task to an ExecutorService happen-before any actions taken by that task.
Upvotes: 4