Введение
Многопоточность в Java — это не просто «фича» языка, а фундаментальная технология, определяющая производительность, отзывчивость и масштабируемость современных приложений.
Создание потоков: Thread и ExecutorService
1.1. Базовые способы создания потоков
// Способ 1: Наследование от Thread class MyThread extends Thread { @Override public void run() { System.out.println("Поток " + Thread.currentThread().getName() + " выполняется"); } } MyThread thread1 = new MyThread(); thread1.start(); // Способ 2: Реализация Runnable Runnable task = () -> { System.out.println("Задача выполняется в потоке: " + Thread.currentThread().getName()); }; Thread thread2 = new Thread(task); thread2.start(); // Способ 3: Callable с возвращаемым значением Callable<Integer> callableTask = () -> { Thread.sleep(1000); return 42; }; Future<Integer> future = executor.submit(callableTask); Integer result = future.get(); // Блокирующий вызов
1.2. Executor Framework (Java 5+)
// Виды пулов потоков ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4); ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); ExecutorService scheduledExecutor = Executors.newScheduledThreadPool(2); // Кастомный ThreadFactory ThreadFactory customFactory = r -> { Thread thread = new Thread(r); thread.setDaemon(true); thread.setPriority(Thread.MAX_PRIORITY); thread.setName("CustomThread-" + thread.getId()); return thread; }; ExecutorService customExecutor = Executors.newFixedThreadPool(4, customFactory); // Запуск задач List<Callable<String>> tasks = Arrays.asList( () -> "Task1", () -> "Task2", () -> "Task3" ); List<Future<String>> futures = executor.invokeAll(tasks);
Синхронизация и блокировки
2.1. Synchronized блоки
// Синхронизация на объекте public class Counter { private int count = 0; // Синхронизированный метод public synchronized void increment() { count++; } // Синхронизированный блок public void decrement() { synchronized (this) { count--; } } // Статическая синхронизация public static synchronized void staticMethod() { // Синхронизация на классе (Counter.class) } }
2.2. ReentrantLock и ReadWriteLock
public class ThreadSafeCache { private final Map<String, Object> cache = new HashMap<>(); private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); private final Lock readLock = lock.readLock(); private final Lock writeLock = lock.writeLock(); public Object get(String key) { readLock.lock(); try { return cache.get(key); } finally { readLock.unlock(); } } public void put(String key, Object value) { writeLock.lock(); try { cache.put(key, value); } finally { writeLock.unlock(); } } // TryLock с таймаутом public boolean tryPerformOperation() { if (writeLock.tryLock(100, TimeUnit.MILLISECONDS)) { try { // Критическая секция return true; } finally { writeLock.unlock(); } } return false; } }
2.3. StampedLock (Java 8+)
public class Point { private double x, y; private final StampedLock sl = new StampedLock(); // Оптимистичная блокировка чтения public double distanceFromOrigin() { long stamp = sl.tryOptimisticRead(); double currentX = x, currentY = y; if (!sl.validate(stamp)) { stamp = sl.readLock(); try { currentX = x; currentY = y; } finally { sl.unlockRead(stamp); } } return Math.sqrt(currentX * currentX + currentY * currentY); } // Апгрейд блокировки public void moveIfAtOrigin(double newX, double newY) { long stamp = sl.readLock(); try { while (x == 0.0 && y == 0.0) { long ws = sl.tryConvertToWriteLock(stamp); if (ws != 0L) { stamp = ws; x = newX; y = newY; break; } else { sl.unlockRead(stamp); stamp = sl.writeLock(); } } } finally { sl.unlock(stamp); } } }
Concurrent коллекции
3.1. Thread-safe коллекции
// ConcurrentHashMap ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("key1", 1); map.compute("key1", (k, v) -> v == null ? 1 : v + 1); map.computeIfAbsent("key2", k -> 42); map.forEach(2, (k, v) -> System.out.println(k + "=" + v)); // Параллельное выполнение // ConcurrentLinkedQueue ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>(); queue.offer("element1"); queue.offer("element2"); String element = queue.poll(); // CopyOnWriteArrayList CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>(); list.add("item1"); list.addIfAbsent("item1"); // Не добавит, так как уже есть // BlockingQueue варианты BlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(100); BlockingQueue<String> linkedBlockingQueue = new LinkedBlockingQueue<>(); BlockingQueue<String> priorityBlockingQueue = new PriorityBlockingQueue<>(); BlockingQueue<String> synchronousQueue = new SynchronousQueue<>(); BlockingQueue<String> delayQueue = new DelayQueue<>();
3.2. Продвинутые паттерны с ConcurrentHashMap
public class ConcurrentCache<K, V> { private final ConcurrentHashMap<K, V> map = new ConcurrentHashMap<>(); private final ConcurrentHashMap<K, Long> timestamps = new ConcurrentHashMap<>(); private final ScheduledExecutorService cleaner = Executors.newScheduledThreadPool(1); public ConcurrentCache(long ttlMillis) { cleaner.scheduleAtFixedRate(this::evictExpired, ttlMillis, ttlMillis, TimeUnit.MILLISECONDS); } public V get(K key) { V value = map.get(key); if (value != null) { timestamps.put(key, System.currentTimeMillis()); } return value; } public void put(K key, V value) { map.put(key, value); timestamps.put(key, System.currentTimeMillis()); } private void evictExpired() { long now = System.currentTimeMillis(); timestamps.forEach((key, timestamp) -> { if (now - timestamp > 60000) { // 60 секунд TTL map.remove(key); timestamps.remove(key); } }); } }
Atomic переменные и CAS операции
4.1. Классы java.util.concurrent.atomic
AtomicInteger atomicInt = new AtomicInteger(0); atomicInt.incrementAndGet(); atomicInt.addAndGet(5); atomicInt.updateAndGet(x -> x * 2); AtomicLong atomicLong = new AtomicLong(); AtomicBoolean atomicBool = new AtomicBoolean(true); // Atomic массивы AtomicIntegerArray atomicArray = new AtomicIntegerArray(10); atomicArray.set(0, 42); atomicArray.getAndAdd(0, 10); // AtomicReference AtomicReference<String> atomicRef = new AtomicReference<>("initial"); atomicRef.compareAndSet("initial", "updated"); // CAS операция // AtomicFieldUpdater public class Account { private volatile int balance; private static final AtomicIntegerFieldUpdater<Account> updater = AtomicIntegerFieldUpdater.newUpdater(Account.class, "balance"); public boolean deposit(int amount) { return updater.compareAndSet(this, balance, balance + amount); } } // Accumulator и Adder для высококонкурентных сценариев LongAdder adder = new LongAdder(); // Эффективнее AtomicLong при высокой конкуренции IntAccumulator accumulator = new IntAccumulator(Integer::max, Integer.MIN_VALUE);
4.2. Пользовательские CAS операции

