# ReentrantLock
相对于synchronized它具备如下特点
- 可中断
- 可以设置超时时间
- 可以设置为公平锁
- 支持多个条件变量
与synchronized一样,都支持可重入
# 语法
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j
public class Demo {
static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
lock.lock();
try {
log.info("do something");
} finally {
lock.unlock();
}
}
}
# 可重入
可重入是指同一个线程如果首次获得了这把锁,那么因为它是这把锁的拥有者,因此有权利再次获取这把锁
如果是不可重入锁,那么第二次获得锁时,自己也会被锁挡住
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j
public class Demo {
static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
lock.lock();
try {
log.info("do something");
method();
} finally {
lock.unlock();
}
}
static void method() {
lock.lock();
try {
log.info("method");
method2();
} finally {
lock.unlock();
}
}
static void method2() {
lock.lock();
try {
log.info("method2");
} finally {
lock.unlock();
}
}
}
# 可打断
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j
public class Demo {
static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
Thread thread = new Thread(() -> {
try {
//如果没有竞争那么此方法就会获取Lock对象锁
//如果有竞争就进入阻塞队列,可以被其它线程用lockInterruptibly方法打断
lock.lockInterruptibly();
} catch (InterruptedException e) {
log.info("未获取到锁");
throw new RuntimeException(e);
}
log.info("获取到锁");
}, "t1");
lock.lock();
thread.start();
try {
log.info("do something");
log.info("打断thread");
thread.interrupt();
} finally {
lock.unlock();
}
}
}
# 锁超时
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j
public class Demo {
static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
new Thread(() -> {
try {
if (!lock.tryLock(1, TimeUnit.SECONDS)) {
log.info("未获取到锁,不继续执行");
return;
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
try {
log.info("获取到锁");
} finally {
lock.unlock();
}
}, "t1").start();
lock.lock();
try {
lock.lock();
log.info("main do something");
} finally {
lock.unlock();
}
}
}
# 公平锁
ReentrantLock默认是不公平的
static ReentrantLock lock = new ReentrantLock(true);
# 条件变量
# 语法
使用流程
- await前需要获得锁
- await执行后,会释放锁,进入conditionObject等待
- await的线程被唤醒 (或打断、或超时)取重新竞争lock锁
- 竞争lock锁成功后,从await后继续执行
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j
public class Demo {
static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
//创建
Condition condition = lock.newCondition();
//需要先加锁
lock.lock();
try {
//进入等待
condition.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
condition.signal();
}
}