class BankAccount {
private int balance = 1000;
// Весь метод синхронизирован. Поток захватывает монитор объекта 'this'
public synchronized void deposit(int amount) {
int temp = balance;
temp += amount; // Операция может быть прервана другим потоком
balance = temp;
}
public synchronized int getBalance() {
return balance;
}
} class BankAccount {
private int balance = 1000;
private final Object lock = new Object(); // ← Специальный объект-замок
public void deposit(int amount) {
// Синхронизируемся на отдельном объекте-замке
synchronized (lock) { // ← Захватываем монитор объекта 'lock'
int temp = balance;
temp += amount;
balance = temp;
} // ← Монитор 'lock' освобождается здесь
}
public int getBalance() {
synchronized (lock) {
return balance;
}
}
} import java.util.concurrent.atomic.AtomicInteger;
class AtomicCounter {
private final AtomicInteger count = new AtomicInteger(0);
public void increment() {
// Эта операция атомарна. Её нельзя прервать.
count.incrementAndGet(); // ← Гарантированно безопасно
}
public int getCount() {
return count.get();
}
}
import java.util.concurrent.locks.ReentrantLock;
class LockBasedCounter {
private final ReentrantLock lock = new ReentrantLock(); // Создаём замок
private int count = 0;
public void increment() {
lock.lock(); // ← Захватываем замок
try {
count++;
} finally {
lock.unlock(); // ← ОБЯЗАТЕЛЬНО освобождаем в блоке finally
}
}
} import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
class DataCache {
private final Map<String, String> cache = new HashMap<>();
private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
public String get(String key) {
rwLock.readLock().lock(); // ← Захватываем замок на чтение
try {
return cache.get(key);
} finally {
rwLock.readLock().unlock();
}
}
public void put(String key, String value) {
rwLock.writeLock().lock(); // ← Захватываем эксклюзивный замок на запись
try {
cache.put(key, value);
} finally {
rwLock.writeLock().unlock();
}
}
}
import java.util.concurrent.Semaphore;
class ConnectionPool {
private final Semaphore semaphore;
// ... пул соединений ...
public ConnectionPool(int poolSize) {
this.semaphore = new Semaphore(poolSize); // ← Создаём семафор с N "разрешениями"
}
public Connection getConnection() throws InterruptedException {
semaphore.acquire(); // ← "Занимаем" место. Если мест нет, ждём.
// ... выдаем соединение из пула ...
return connection;
}
public void releaseConnection(Connection connection) {
// ... возвращаем соединение в пул ...
semaphore.release(); // ← "Освобождаем" место для другого потока.
}
} import java.util.concurrent.CountDownLatch;
public class RaceDemo {
public static void main(String[] args) throws InterruptedException {
int runnerCount = 5;
CountDownLatch startSignal = new CountDownLatch(1); // Пистолет
CountDownLatch finishLine = new CountDownLatch(runnerCount); // Финишная черта
for (int i = 0; i < runnerCount; i++) {
new Thread(new Runner(startSignal, finishLine)).start();
}
System.out.println("На старт... Внимание...");
Thread.sleep(1000);
startSignal.countDown(); // ← БАМ! Все потоки бегут одновременно
System.out.println("Ждём, когда все финишируют...");
finishLine.await(); // ← Главный поток ждёт здесь
System.out.println("Забег окончен!");
}
}
class Runner implements Runnable {
private final CountDownLatch startSignal;
private final CountDownLatch finishLine;
Runner(CountDownLatch startSignal, CountDownLatch finishLine) {
this.startSignal = startSignal;
this.finishLine = finishLine;
}
@Override
public void run() {
try {
startSignal.await(); // ← Ждём сигнала старта
System.out.println(Thread.currentThread().getName() + " бежит!");
Thread.sleep((long) (Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
finishLine.countDown(); // ← Пересекли финишную черту
}
}
}