Попытка захвата замка в Java
Метод tryLock() у Lock сразу
возвращает true, если замок свободен, и
false, если его уже держит другой поток.
Так удобно откладывать работу или пробовать снова
через паузу.
Перегрузка tryLock(long time, TimeUnit unit)
ждет не дольше заданного интервала и тоже отвечает
логическим значением. При успехе не забывают
unlock() в finally.
Один поток держит замок, второй пробует зайти без ожидания:
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Main {
private static final Lock gate = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
gate.lock();
try {
Thread rival = new Thread(() -> {
boolean ok = gate.tryLock();
System.out.println("try now: " + ok);
if (ok) {
try {
System.out.println("inside");
} finally {
gate.unlock();
}
}
});
rival.start();
rival.join();
} finally {
gate.unlock();
}
}
}
Вариант с ограничением ожидания на сто миллисекунд:
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Main {
private static final Lock gate = new ReentrantLock();
static boolean enterWithWait() throws InterruptedException {
if (gate.tryLock(100, TimeUnit.MILLISECONDS)) {
try {
System.out.println("entered");
return true;
} finally {
gate.unlock();
}
}
return false;
}
public static void main(String[] args) throws InterruptedException {
Thread holder = new Thread(() -> {
gate.lock();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
gate.unlock();
}
});
holder.start();
Thread.sleep(20);
System.out.println(enterWithWait());
holder.join();
}
}
Замок и счетчик attempts. Пять потоков
до 10 раз вызывают tryLock():
при успехе увеличивают счетчик и сразу
освобождают замок. Напечатайте число удачных
захватов.