Атомарные переменные в Java с примерами
При многопоточности совместно используемый объект чаще всего приводит к проблеме, когда включен параллелизм. Общая сущность, такая как изменяемый объект или переменная, может быть изменена, что может привести к несогласованности программы или базы данных. Таким образом, становится критически важным иметь дело с разделяемым объектом при одновременном доступе. Атомарная переменная может быть одной из альтернатив в таком сценарии.
Java предоставляет атомарные классы, такие как AtomicInteger, AtomicLong, AtomicBoolean и AtomicReference . Объекты этих классов представляют собой атомарную переменную типа int, long, boolean и ссылку на объект соответственно. Эти классы содержат следующие методы.
- set (int value): устанавливает заданное значение
- get (): получает текущее значение
- lazySet (int value): в конце концов устанавливается на заданное значение
- compareAndSet (int expect, int update): атомарно устанавливает значение для данного обновленного значения, если текущее значение == ожидаемое значение
- addAndGet (int delta): атомарно добавляет заданное значение к текущему значению.
- DecmentAndGet (): атомарно уменьшает на единицу текущее значение
Пример:
// Атомарная переменная AtomicInteger var;
Потребность в атомарной переменной
Рассмотрим пример ниже:
В однопоточной среде вышеупомянутый класс даст только ожидаемый результат. Но когда речь идет о многопоточной среде, это может привести к противоречивым результатам. Это происходит потому, что обновление «var» выполняется в три этапа: чтение, обновление и запись. Если два или более потока попытаются обновить значение одновременно, оно может не обновиться должным образом.
Эту проблему можно решить с помощью блокировки и синхронизации, но неэффективно.
- Использование аналогии с блокировкой или синхронизацией: синхронизация или блокировка могут решить нашу проблему, но это ставит под угрозу эффективность использования времени или производительность. Во-первых, он предписывает планировщику ресурсов и потоков управлять блокировкой. Во-вторых, когда несколько потоков пытаются получить блокировку, только один из них выигрывает, остальные приостанавливаются или блокируются. Приостановка или блокировка потоков может иметь огромное влияние на производительность.
import
java.io.*;
import
java.util.concurrent.locks.*;
class
Counter
extends
Thread {
// Counter Variable
int
count =
0
;
// method which would be called upon
// the start of execution of a thread
public
synchronized
void
run()
{
int
max = 1_000_00_000;
// incrementing counter total of max times
for
(
int
i =
0
; i < max; i++) {
count++;
}
}
}
public
class
SynchronizedCounter {
public
static
void
main(String[] args)
throws
InterruptedException
{
// Instance of Counter Class
Counter c =
new
Counter();
// Defining Two different threads
Thread first =
new
Thread(c,
"First"
);
Thread second =
new
Thread(c,
"Second"
);
// Threads start executing
first.start();
second.start();
// main thread will wait for both
// threads to complete execution
first.join();
second.join();
// Printing final value of count variable
System.out.println(c.count);
}
}
Выход:200000000
- Использование атомарной переменной:
import
java.util.concurrent.atomic.AtomicInteger;
class
Counter
extends
Thread {
// Atomic counter Variable
AtomicInteger count;
// Constructor of class
Counter()
{
count =
new
AtomicInteger();
}
// method which would be called upon
// the start of execution of a thread
public
void
run()
{
int
max = 1_000_00_000;
// incrementing counter total of max times
for
(
int
i =
0
; i < max; i++) {
count.addAndGet(
1
);
}
}
}
public
class
AtomicCounter {
public
static
void
main(String[] args)
throws
InterruptedException
{
// Instance of Counter Class
Counter c =
new
Counter();
// Defining Two different threads
Thread first =
new
Thread(c,
"First"
);
Thread second =
new
Thread(c,
"Second"
);
// Threads start executing
first.start();
second.start();
// main thread will wait for both
// threads to complete execution
first.join();
second.join();
// Printing final value of count variable
System.out.println(c.count);
}
}
Выход:200000000
Вниманию читателя! Не прекращайте учиться сейчас. Ознакомьтесь со всеми важными концепциями Java Foundation и коллекций с помощью курса "Основы Java и Java Collections" по приемлемой для студентов цене и будьте готовы к работе в отрасли. Чтобы завершить подготовку от изучения языка к DS Algo и многому другому, см. Полный курс подготовки к собеседованию .