Интерфейс Lock API : существует с Java 1.5.
Базовый интерфейс из lock framework, предоставляющий более гибкий подход по ограничению доступа к ресурсам/блокам нежели при использовании synchronized. Так, при использовании нескольких локов, порядок их освобождения может быть произвольный. Плюс имеется возможность пойти по альтернативному сценарию, если лок уже кем то захвачен.
public class ReentrantLockExample {
public static void main(String[] args) throws InterruptedException {
Resource resource = new Resource(6, 14);
MyThread thread1 = new MyThread(resource);
thread1.setName("firstThread");
MyThread thread2 = new MyThread(resource);
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(resource.getI());
System.out.println(resource.getPhone());
}
}
class MyThread extends Thread {
private final Resource resource;
MyThread(Resource res) {
resource = res;
}
@Override
public void run() {
resource.incrementI();
}
}
class Resource {
private int i;
public int getPhone() {
return phone;
}
Resource(int i, int phone) {
this.i = i;
this.phone = phone;
}
private int phone;
private final Lock lock = new ReentrantLock();
void incrementI() {
lock.lock();
int iLocal = this.i;
if (Thread.currentThread().getName().equals("firstThread")) {
Thread.yield();
}
iLocal++;
this.i = iLocal;
incrementPhone();
}
void incrementPhone() {
int phoneLocal = this.phone;
if (Thread.currentThread().getName().equals("firstThread")) {
Thread.yield();
}
phoneLocal++;
this.phone = phoneLocal;
lock.unlock();
}
int getI() {
return i;
}
}
public class ConditionsExample {
private static Lock lock = new ReentrantLock();
private static Condition condition = lock.newCondition();
private static int bankAccount =0;
public static void main(String[] args) {
new AccountMinusMoney().start();
new AccountPlusMoney().start();
}
static class AccountPlusMoney extends Thread{
@Override
public void run() {
lock.lock();
bankAccount +=10;
System.out.println("\n ------ прибавили 10 руб. \n");
condition.signal();
lock.unlock();
}
}
static class AccountMinusMoney extends Thread {
@Override
public void run() {
if(bankAccount < 10){
try {
lock.lock();
System.out.println("не можем списать деньги так как сумма на счету меньше 10 руб. =(");
System.out.println("... ждём ... другой поток .... ");
condition.await();
lock.unlock();
System.out.println("... другой поток отработал ... продолжаем ! =) ");
}catch (InterruptedException e){
e.printStackTrace();
}
}
bankAccount -=10;
System.out.println("\n ------ отняли 10 руб.\n");
System.out.println();
}
}
}