Concorrenza Java - AtomicInteger Class
Una classe java.util.concurrent.atomic.AtomicInteger fornisce operazioni sul valore int sottostante che può essere letto e scritto in modo atomico e contiene anche operazioni atomiche avanzate. AtomicInteger supporta operazioni atomiche sulla variabile int sottostante. Ha metodi get e set che funzionano come letture e scritture su variabili volatili. Cioè, un insieme ha una relazione accade prima con qualsiasi successivo get sulla stessa variabile. Anche il metodo compareAndSet atomico ha queste caratteristiche di coerenza della memoria.
Metodi AtomicInteger
Di seguito è riportato l'elenco dei metodi importanti disponibili nella classe AtomicInteger.
Sr.No. | Metodo e descrizione |
---|---|
1 | public int addAndGet(int delta) Atomicamente aggiunge il valore dato al valore corrente. |
2 | public boolean compareAndSet(int expect, int update) Atomicamente imposta il valore sul valore aggiornato dato se il valore corrente è uguale al valore atteso. |
3 | public int decrementAndGet() Decrementa atomicamente di uno il valore corrente. |
4 | public double doubleValue() Restituisce il valore del numero specificato come double. |
5 | public float floatValue() Restituisce il valore del numero specificato come float. |
6 | public int get() Ottiene il valore corrente. |
7 | public int getAndAdd(int delta) Atomiclly aggiunge il valore dato al valore corrente. |
8 | public int getAndDecrement() Decrementa atomicamente di uno il valore corrente. |
9 | public int getAndIncrement() Atomicamente incrementa di uno il valore corrente. |
10 | public int getAndSet(int newValue) Atomicamente imposta il valore dato e restituisce il vecchio valore. |
11 | public int incrementAndGet() Atomicamente incrementa di uno il valore corrente. |
12 | public int intValue() Restituisce il valore del numero specificato come int. |
13 | public void lazySet(int newValue) Alla fine si imposta sul valore dato. |
14 | public long longValue() Restituisce il valore del numero specificato come long. |
15 | public void set(int newValue) Imposta il valore dato. |
16 | public String toString() Restituisce la rappresentazione String del valore corrente. |
17 | public boolean weakCompareAndSet(int expect, int update) Atomicamente imposta il valore sul valore aggiornato dato se il valore corrente è uguale al valore atteso. |
Esempio
Il seguente programma TestThread mostra un'implementazione non sicura di counter in un ambiente basato su thread.
public class TestThread {
static class Counter {
private int c = 0;
public void increment() {
c++;
}
public int value() {
return c;
}
}
public static void main(final String[] arguments) throws InterruptedException {
final Counter counter = new Counter();
//1000 threads
for(int i = 0; i < 1000 ; i++) {
new Thread(new Runnable() {
public void run() {
counter.increment();
}
}).start();
}
Thread.sleep(6000);
System.out.println("Final number (should be 1000): " + counter.value());
}
}
Ciò può produrre il seguente risultato a seconda della velocità del computer e dell'interleaving dei thread.
Produzione
Final number (should be 1000): 1000
Esempio
Il seguente programma TestThread mostra un'implementazione sicura del contatore utilizzando AtomicInteger in un ambiente basato su thread.import java.util.concurrent.atomic.AtomicInteger;
public class TestThread {
static class Counter {
private AtomicInteger c = new AtomicInteger(0);
public void increment() {
c.getAndIncrement();
}
public int value() {
return c.get();
}
}
public static void main(final String[] arguments) throws InterruptedException {
final Counter counter = new Counter();
//1000 threads
for(int i = 0; i < 1000 ; i++) {
new Thread(new Runnable() {
public void run() {
counter.increment();
}
}).start();
}
Thread.sleep(6000);
System.out.println("Final number (should be 1000): " + counter.value());
}
}
Questo produrrà il seguente risultato.
Produzione
Final number (should be 1000): 1000