AtomicInteger activation does not behave as expected

I read about AtomicInteger and how its operations are atomic and how these properties make it useful for multithreading.

I wrote the following program to test the same.

I expect the final set size to be 1000, since each loop thread is 500 times and every time the thread calls getNext (), it should get a unique number.

But the output is always less than 1000. What am I missing here?

public class Sequencer {

private final AtomicInteger i = new AtomicInteger(0);

public int getNext(){
    return i.incrementAndGet();
}

public static void main(String[] args) {

    final Sequencer seq = new Sequencer();

    final Set<Integer> set = new HashSet<Integer>();

    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            for (int i=0; i<500; i++)
                set.add(seq.getNext());

        }
    },"T1");
    t1.start();


    Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            for (int i=0; i<500; i++)
                set.add(seq.getNext());

        }
    },"T2");

    t2.start();

    try {
        t1.join();
        t2.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    System.out.println(set.size());

}

}

+4
source share
4 answers

, HashSet . , , , AtomicInteger .

ConcurrentLinkedQueue.

:. : , , Atomic-. , , add.

, . , , synchronized . , , synchronized .

+3

HashSet , . Vector , , HashSet.

t1.start();
t1.join();

t2.start();
t2.join();
+1

, - , HashSet .

-, , AtomicInteger , , . . , . , , , , ( set). . , . , HashSet , AtomicInteger.

, , . onlyf add() s, add() - , , . - HashMap add(), (, , , , , ):

class HashMap {
 int valueToAdd;
 public add(int valueToAdd) {
   this.valueToAdd = valueToAdd;
   addToBackingStore(this.valueToAdd);
 }
}

add(), addToBackingStore() , this.valueToAdd, valueToAdd, .

, , .

0

, .

public class Sequencer {

    private final AtomicInteger i = new AtomicInteger(0);

    public static void main(String[] args) {

        final Sequencer seq = new Sequencer();

        final Set<Integer> notSafe = new HashSet<Integer>();
        final Set<Integer> set = Collections.synchronizedSet(notSafe);
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 500; i++)
                    set.add(seq.getNext());

            }
        }, "T1");
        t1.start();


        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 500; i++)
                    set.add(seq.getNext());

            }
        }, "T2");

        t2.start();

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(set.size());

    }

    public int getNext() {
        return i.incrementAndGet();
    }
}
-1

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


All Articles