Ответ
Lock — это интерфейс из пакета java.util.concurrent.locks, предоставляющий более гибкие и расширенные возможности для синхронизации потоков по сравнению с ключевым словом synchronized.
Ключевые реализации: ReentrantLock, ReentrantReadWriteLock.
Основные отличия Lock от synchronized:
| Характеристика | synchronized |
Lock (например, ReentrantLock) |
|---|---|---|
| Гибкость | Встроенное в язык, ограниченное. | Явный API с большим контролем. |
| Попытка захвата | Только блокировка с ожиданием. | Возможность попытки захвата с таймаутом (tryLock(long time, TimeUnit unit)). |
| Прерываемость | Не прерываемое ожидание. | Прерываемое ожидание (lockInterruptibly()). |
| Честность | Не гарантирует порядок (нечестный). | Может быть сконфигурирован как честный (fair lock). |
| Условия | Одно условие ожидания (wait/notify). | Поддержка множества условий (Condition). |
Пример использования ReentrantLock:
import java.util.concurrent.locks.*;
class Counter {
private final Lock lock = new ReentrantLock();
private int count = 0;
public void increment() {
lock.lock(); // Захватываем блокировку
try {
count++;
} finally {
lock.unlock(); // Всегда освобождаем в finally
}
}
public int getCount() {
lock.lock();
try {
return count;
} finally {
lock.unlock();
}
}
}
Когда использовать Lock: когда нужны расширенные функции (таймауты, честность, несколько условий). Когда использовать synchronized: для простых случаев, где его возможностей достаточно, так как это более лаконично и менее подвержено ошибкам (автоматическое освобождение).
Ответ 18+ 🔞
А, ну вот, смотри, опять про эти ваши блокировки потокам рассказывать. Ну, типа, есть у нас в Java такая штука — Lock. Это, блядь, не просто synchronized, который в язык впаян, а целый интерфейс из java.util.concurrent.locks. По сути, тот же замок, но с прибамбасами, как у швейцарского ножа, а не просто тупой ключ.
Основные приблуды, которые там есть: ReentrantLock, ReentrantReadWriteLock. Первый — это просто крутой замок, второй — уже с разделением на «почитать» и «пописать», ну ты понял.
А теперь, сука, в чём разница между старым добрым synchronized и этим новым Lock? Давай табличкой, а то мозги заплетутся:
| Признак | synchronized (дедовский способ) |
Lock (например, ReentrantLock) |
|---|---|---|
| Гибкость | Жёстко в языке, нихуя не настроишь. | Явное API, можно крутить-вертеть как хочешь. |
| Попытка захвата | Либо взял, либо стоишь и ждёшь, пока в говне не утонешь. | Можно попробовать взять с таймаутом (tryLock), типа «давай, пять секунд, и я пошёл». |
| Прерываемость | Если поток в ожидании, его нихуя не прервать. | Можно прервать ожидание (lockInterruptibly()), крикнуть потоку «эй, давай, завязывай!». |
| Честность | Очередь не гарантирует, кто первый прибежал — тот может и последним оказаться. | Можно сделать честным (fair lock), чтобы очередь соблюдалась, как в советской поликлинике. |
| Условия (Condition) | Одно общее условие на всех (wait()/notify()), толку — ноль, ебать. |
Можно создать сколько угодно отдельных условий (newCondition()), чтобы одни ждали одно, а другие — другое. Красота! |
Вот, смотри, как этим пользоваться на практике:
import java.util.concurrent.locks.*;
class Counter {
private final Lock lock = new ReentrantLock(); // Вот он, наш красавец
private int count = 0;
public void increment() {
lock.lock(); // Захватываем, блядь, замок
try {
count++; // Делаем дело
} finally {
lock.unlock(); // ОБЯЗАТЕЛЬНО отпускаем в finally, а то все повиснут, пидарасы!
}
}
public int getCount() {
lock.lock();
try {
return count;
} finally {
lock.unlock();
}
}
}
Так когда же эту хуйню использовать? Да когда тебе мало возможностей synchronized! Ну, типа, нужен таймаут, или честность, или несколько очередей ожидания. А если всё просто — бери synchronized, он короче и меньше шансов накосячить, потому что сам отпускается. А с Lock забудешь unlock() в finally написать — и пиши пропало, deadlock тебе в сраку, все потоки уснут навеки. Так что думай, ебаклак, что тебе нужнее.