I have multiple threads accessing class Aufzahlen
and incrementing the cc variable. I wonder if i don't put cc on volatile but my method on synchronized is there any room for error here? Since the cc variable will only be accessed once at a time.
Is it still possible for threads to have the cc variable in there own cache and therefor mess with it? I had been running this code example for a while now and didn't find any errors so far.
public class Aufzahlen {
private int cc=1;
public synchronized void aufzahlen() throws InterruptedException {
cc = cc +1;
}
public synchronized void printa() {
// TODO Auto-generated method stub
System.out.println("Thread: " + Thread.currentThread() + "Zahl: " + cc);
}
{
This method will not fail. If you synchronize every time you access a field, changes to it are guaranteed to be visible every time a thread holds the same lock, as demonstrated below:
From Java Concurrency In Practice [pdf], figure 3.1
So it is not neccessary to make the field volatile. You are probably much better off by using AtomicInteger
's getAndIncrement()
and incrementAndGet()
methods, which serve the same purpose, but with better concurrency throughput (they use native functionality instead of locking, they have been designed for exactly this task) - but make sure that memory visbility of the AtomicInteger
itself is given (the easiest way to do this is make it final - it won't make the AtomicInteger
's value final).
public class Aufzahlen {
private final AtomicInteger atomicInt = new AtomicInteger(1); // set initial value with constructor argument
public void aufzahlen() {
atomicInt.incrementAndGet();
} // no need for synchronization because updates are atomic and are automatically visible
}
I might have used "atomic" once or twice in this post, it means that no two threads may be concurrently executing the same code, or, in other words, that the operation cannot be "divided" into multiple parts that multiple threads could be inside of concurrently.
+--- Function aufzählen() without synchronization and with i++ ---------------+
| |
| [Get i from field] --> [Increment i locally] --> [Write new value to field] |
| ^ ^ |
| | | |
| "Race condition", multiple threads could be at these stages |
| -> operation not atomic |
+-----------------------------------------------------------------------------+
I just demonstated what is not atomic, you can make this operation atomic by using synchronized
(the next thread needs to wait for the first to finish the whole method) or you could use AtomicInteger
which does this atomicity for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With