Is this multi-threaded code guaranteed to always return zero?

I am taking a book to do a test test, I found this question:

import java.util.concurrent.atomic.AtomicInteger;

class AtomicVariableTest {

    private static AtomicInteger counter = new AtomicInteger(0);

    static class Decrementer extends Thread {

        public void run() {
            counter.decrementAndGet(); // #1
        }
    }

    static class Incrementer extends Thread {

        public void run() {
            counter.incrementAndGet(); // #2
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            new Incrementer().start();
            new Decrementer().start();
        }
        System.out.println(counter);
    }
}

Answer:

This program will always print 0.

But I think there is no guarantee that the threads will be completed when it prints the counter value.

I mean that most of the time it will return 0, but if you strictly adhere to the theory, this does not guarantee this.

Am I right?

+4
source share
1 answer

Guaranteed. And not guaranteed. There is no middle place.

, . , - !

, , :

counter.decrementAndGet();    // #1
System.out.println(counter);  // Main thread
counter.incrementAndGet();    // #2
// (and so on, at some arbitrary point after the print)

/ Java ( JLS) "before-before".

( ), - - , , , .

public static void main(String[] args) {
    final List<Thread> threads = new ArrayList<>();
    for (int i = 0; i < 5; i++) {
        final new Incrementer i = new Incrementer();
        threads.add(i);
        i.start();
        final new Decrementer d = new Decrementer();
        threads.add(d);
        d.start();
    }
    for (final Thread t : threads) { t.join(); }
    System.out.println(counter);
}

. : : Java

ExecutorService ExecutorCompletionService , .

+10

Source: https://habr.com/ru/post/1606524/


All Articles