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; } }
Часто используется как счетчик. Предотвращает Race conditions
Compare and Swap(CAS) - паттерн который используют Atomic классы. Оптимистическая блокировка.