10

I know increment operation is not atomic in C++ without locking.

Will JVM add any lock on its implementation of iinc instruction?

StarPinkER
  • 14,081
  • 7
  • 55
  • 81

6 Answers6

16

No its not

  • Retrieve the current value of c.
  • Increment the retrieved value by 1.
  • Store the incremented value back in c.

Java Documentation for Atomicity and Thread Interference

You need to either use synchronized keyword or use AtomicXXX methods for Thread safety.

UPDATE:

public synchronized void increment() {
    c++;
}

or

AtomicInteger integer = new AtomicInteger(1);
//somewhere else in code
integer.incrementAndGet();

Also read: Is iinc atomic in Java?

Narendra Pathai
  • 41,187
  • 18
  • 82
  • 120
  • you should read the concurrency documentation of Java which is quite nice for understanding the basic concepts of Java Concurrency. – Narendra Pathai Mar 08 '13 at 05:43
  • +1 for good references. To be pedantic, I believe `integer.getAndIncrement()` is the equivalent of `i++` (not `incrementAndGet()`)! – Muel Mar 08 '13 at 05:52
  • This is not the correct answer. `i++` compiled to `iinc` for local variables, where concurrency is **not** a concern. If `i` is a field, then it's compiled as @Ellen Spertus's answer, where proper synchronization is needed. Related to this topic, this question has a good answer: https://stackoverflow.com/questions/25168062/why-is-i-not-atomic – Efe Kahraman Jun 18 '17 at 10:48
  • @EfeKahraman so does this mean that the Java bytecode instruction `iinc` is thread-safe or not? – Nearoo Mar 08 '18 at 20:40
  • Nevermind, I found an answer: [`iirc` is only applicable to local variables, thus thread safety is irrelevant.](https://stackoverflow.com/a/30269266/3424423) – Nearoo Mar 08 '18 at 20:45
13

The answer to your question depends on whether you mean the IINC instruction or, what other answers are referring to, the ++ operator.

Using ++ on a static or instance field is nothing more than get, increment, and set, thus it is not atomic (the other answers explain this in more detail).

But

Since you asked if the IINC instruction is atomic, this is not the real answer. In fact, none of the answers to this question address the instruction, all of them seem to be based around the operator being used on instance or static fields.


The IINC instruction only operates on local variables. As the name suggests, they are only local, and only accessible from a very limited scope. Thus, it is not possible to access a local variable from another Thread. This means that it doesn't matter whether or not the instruction is atomic.

Clashsoft
  • 11,553
  • 5
  • 40
  • 79
5

Not it's not and it can cause real problems. This test is supposed to print 200000000 but it doesnt due to thread interference

static int n;

public static void main(String[] args) throws InterruptedException {
    Runnable r = new Runnable() {
        public void run() {
            for(int i = 0; i < 100000000; i++) {
                n++;
            }
        }
    };
    Thread t1 = new Thread(r);
    Thread t2 = new Thread(r);
    t1.start();
    t2.start();
    t1.join();
    t2.join();
    System.out.println(n);
}

Note that volatile does not solve the problem.

Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
  • 2
    Actually, this code does not even use the `IINC` instruction to increment the `n` field. `IINC` is only used for local variables, and in this case only for `i++`. – Clashsoft May 10 '15 at 11:39
2

No it is not atomic, the bytecode can get interleaved with other threads.

fguchelaar
  • 4,779
  • 23
  • 36
0

i++ is not atomic in java.
It is better to use

AtomicInteger atomic= new AtomicInteger(1);

There are methods defined like

atomic.getAndDecrement();
atomic.getAndIncrement();
atomic.decrementAndGet();
atomic.incrementAndGet();

any operation with above method would be atomic.

This class comes under java.util.concurrent.atomic package. Java 1.5 has added many features for thready safety and thread concurrency.

AmitG
  • 10,365
  • 5
  • 31
  • 52
0

It is not atomic. Here is the generated byte code for an post-increment of a static int:

0 getstatic 18;    // Load value of variable.
3 iconst_1;
4 iadd;
5 putstatic 18;    // Store value.
Ellen Spertus
  • 6,576
  • 9
  • 50
  • 101