AtomicInteger в Java

AtomicInteger в Java

AtomicInteger е атомен целочислен тип данни, който е част от библиотеката java.util.concurrent. Атомните типове данни гарантират, че достъпът до променливи от множество нишки е синхронизиран, предотвратявайки състезания. AtomicInteger осигурява атомен достъп и актуализации на стойността на целочислените числа, което го прави идеален за споделяне на целочислени стойности между нишки без използване на допълнителни механизми за синхронизация като ключалки.

Създаване на AtomicInteger

AtomicInteger може да се създаде чрез конструиране с целочислена стойност или без параметри, като в този случай стойността се задава на 0 по подразбиране.

java
AtomicInteger atomicInteger = new AtomicInteger(10);

Методи на AtomicInteger

AtomicInteger предоставя набор от методи за атомни актуализации на целочислената си стойност без риск от състезания.

Получаване и задаване на стойността:

* get(): Връща текущата стойност на AtomicInteger.
* set(int newValue): Задава нова стойност за AtomicInteger.

Атомни актуализации:

* incrementAndGet(): Инкрементира стойността на AtomicInteger и връща новата стойност.
* decrementAndGet(): Декрементира стойността на AtomicInteger и връща новата стойност.
* addAndGet(int delta): Добавя указания делта към стойността на AtomicInteger и връща новата стойност.
* compareAndSet(int expectedValue, int newValue): Задава нова стойност само ако текущата стойност съответства на очакваната стойност.

  Избор на правилния CSS препроцесор

Примери за използване

Следните примери демонстрират как да използваме AtomicInteger:

java
// Състезание на нишки за увеличаване на обща целочислена стойност
int sharedValue = 0;

// Нишка 1
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
sharedValue++;
}
});

// Нишка 2
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
sharedValue++;
}
});

thread1.start();
thread2.start();

thread1.join();
thread2.join();

// Изходът ще бъде по-малък от 2000 поради състезанието на нишките
System.out.println("Крайна стойност: " + sharedValue);

java
// Използване на AtomicInteger за атомно увеличаване на стойността
AtomicInteger atomicInteger = new AtomicInteger(0);

// Нишка 1
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
atomicInteger.incrementAndGet();
}
});

// Нишка 2
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
atomicInteger.incrementAndGet();
}
});

thread1.start();
thread2.start();

thread1.join();
thread2.join();

// Изходът ще бъде 2000, тъй като AtomicInteger гарантира атомни операции
System.out.println("Крайна стойност: " + atomicInteger.get());

Заключение

AtomicInteger в Java е мощен инструмент за атомен достъп и актуализации на целочислени стойности, които се споделят между множество нишки. Чрез предотвратяването на състезания на нишки, AtomicInteger гарантира, че целочислените стойности остават последователни и верни дори при едновременен достъп от множество нишки. Това го прави идеален за ситуации, където е необходимо да се поддържат точни целочислени стойности в споделена среда на нишки.

Често задавани въпроси

1. Какво представлява AtomicInteger в Java?

AtomicInteger е атомен целочислен тип данни, който осигурява атомен достъп и актуализации на целочислени стойности без използване на ключалки или други механизми за синхронизация.

2. Защо да използвам AtomicInteger?

AtomicInteger е полезен, когато е необходимо да се споделят целочислени стойности между множество нишки без риск от състезания, които могат да доведат до несъответствия в данните.

3. Как да създам AtomicInteger?

Можете да създадете AtomicInteger чрез конструиране с целочислена стойност или без параметри, като в този случай стойността се задава на 0 по подразбиране.

4. Какви методи предоставя AtomicInteger?

AtomicInteger предоставя методи за получаване и задаване на стойността, както и атомни методи за актуализиране като incrementAndGet(), decrementAndGet() и addAndGet().

5. Как AtomicInteger предотвратява състезания на нишки?

AtomicInteger използва атомни операции, които се изпълняват неразделно и гарантират, че целочислената стойност се актуализира последователно, независимо колко нишки достъпват променливата едновременно.

6. Кога трябва да използвам AtomicInteger вместо обикновена целочислена променлива?

Трябва да използвате AtomicInteger, когато целочислената стойност се споделя от множество нишки и е от съществено значение да се поддържа нейната последователност и точност.

7. Как се различава AtomicInteger от volatile променлива?

volatile променливите гарантират, че актуализациите се виждат от всички нишки, но не осигуряват атомен достъп. AtomicInteger, от друга страна, осигурява атомен достъп и гарантира последователност на данните дори при едновременен достъп.

8. Какво е compareAndSet() методът в AtomicInteger?

Методът compareAndSet() позволява атомично задаване на нова стойност само ако текущата стойност съответства на очакваната стойност. Това е полезно за проверяване и актуализиране на целочислени стойности с гаранция, че между тях не се е случило друго актуализиране.

9. AtomicInteger ли е потокобезопасен?

Да, AtomicInteger е потокобезопасен и позволява безопасен споделен достъп до целочислени стойности от множество нишки.

10. Как AtomicInteger се справя с изключенията?

AtomicInteger не се справя с изключенията. Ако в операцията на AtomicInteger се хвърли изключение, тя ще се разпространи от метода. Препоръчително е да уловите изключенията ръчно при работа с AtomicInteger.