Это пакет в java.util предназначенный для работы с многопоточность.
synchronized - это ключевое слово, которое позволяет заблокировать доступ к методу или части кода, если его уже использует другой поток. По принципу Mutex. Все остальные потоки которые попробуют получить монитор, станут wait(). После выхода из монитора вызывается - notify().
private Object key = new Object();
synchronized (key) {
System.out.println("Hi I'm synchronized block!");
}
synchronized void myMethod() {
System.out.println("Hi I'm synchronized method!");
}
Можно воспринимать так:
void myMethod() {
synchronized(this) {
System.out.println("Hi I'm synchronized method!");
}
}
Для статического метода передается ".class". По этому статическая блокировка и не статическая, на одном классе не будут блокировать друг друга:
static void myMethod() {
synchronized(MyObject.class) {
System.out.println("Hi I'm synchronized method!");
}
}
Минус synchronized - другие потоки вынуждены ждать, пока нужный объект или метод освободится "bottle neck". Если у объекта два синхронизированных метода, два потока не могут одновременно зайти в два синхронизированных метода одного и того же объекта.
volatile - ключевое слово для переменной. Указывает что переменная может быть изменена многими потоками.
Пример
public class VolatileExample {
private static volatile boolean flag = false;
public static void main(String[] args) {
// create and start a new thread
new Thread(() -> {
while (!flag) {
// do some work
}
System.out.println("Thread finished");
}).start();
// set the flag to true after a delay
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
flag = true;
}
}
Пакет для атомарных(неделимые) изменений и операций, которые выполняются независимо и безопасно для многопоточности, без использования synchronized или Lock, что уменьшает риск Deadlock или Race conditions.
Часто используется как счетчик/генератор уникальных ID.
Compare and Swap(CAS) - механизм который используют Atomic классы. который поддерживается на уровне процессора.
Часто быстрее чем синхронизация или блокировка(lock-free). Оптимистическая блокировка.
public class Counter {
private final AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.incrementAndGet(); // атомарное ++
}
public int get() {
return count.get();
}
}
Значение могло измениться на «A → B → A». Для простых счётчиков это не критично, но в сложных структурах данных используют AtomicStampedReference. Необходимо только если значение может отниматься.