Are IF statements and loops such as while or do while atomic instructions in concurrent programming?
If not, is there a way to implement them atomically?
edit: Fixed some of my dodgy English.
In Java the only things which are atomic without any extra work are assignments. Anything else requires synchronisation, either via declaring method synchronized
or using synchronized
block. You can also use classes from java.concurrent
- some of them use some more clever mechanisms to ensure synchronisation, rather than just declaring method synchronized
what tends to be slow.
Regarding if-statement and the question you asked in the comment about comparison n == m
:
Comparison is not atomic. First value of n
has to be loaded (here value of m
can still change), then value of m
has to be loaded and then the actual comparison is evaluated (and at this point the actual values of both n
and m
can be already different than in the comparison).
If you want it synchronised you would have to do something like this:
public class Test {
private static final Object lock = new Object();
public static void main(String[] args) {
if (equals(1, 2)) {
// do something (not synchronised)
}
}
public static boolean equals(int n, int m) {
synchronized (lock) {
return n == m;
}
}
}
However this raises a question why do you want to do this and what should be the lock (and what threads is the lock shared with)? I would like to see some more context about your problem, because currently I cannot see any reason of doing something like this.
You should also remember that:
Integer
)null
will result in NullPointerException
t1
acquires a lock on new Integer(1)
while t2
acquires a lock on new Integer(2)
. So even though both threads lock on n
, they can still be doing things in parallel.public class Test {
private static Integer n = 1;
public static void main(String[] args) throws Exception {
Thread t1 = new Thread(() -> {
synchronized (n) {
System.out.println("thread 1 started");
sleep(2000);
System.out.println("thread 1 finished");
}
});
Thread t2 = new Thread(() -> {
synchronized (n) {
System.out.println("thread 2 started");
sleep(2000);
System.out.println("thread 2 finished");
}
});
t1.start();
sleep(1000);
n = 2;
t2.start();
t1.join();
t2.join();
}
private static void sleep(int millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
Have you considered using mutable AtomicInteger
?