ReentrantLock
与synchronized相比有以下特点
- 可中断
- 可以设置为公平锁
- 支持多个条件变量
与sychronized一样的
- 支持可重入锁
- 可打断锁(避免死锁):使用lockInterruptibly()方法
public class TestReentrant {
private static ReentrantLock lock=new ReentrantLock();
public static void main(String[] args) {
Thread thread = new Thread(() -> {
try {
System.out.println("尝试获取锁");
//如果没有竞争此方法会获取锁
//有竞争则进入阻塞队列,可以被其他线程用interrupt方法打断
lock.lockInterruptibly();
} catch (InterruptedException i) {
System.out.println("没有获取到锁");
i.printStackTrace();
return;
}
try {
System.out.println("获取锁成功");
} finally {
lock.unlock();
}
});
lock.lock();
thread.start(); //主线程拿走锁,使thread线程进入阻塞状态
// thread.interrupt(); //打断该线程避免死锁
}
}
锁超时
- 设置锁超时
reentrantLock.tryLock(2, TimeUnit.SECONDS)//尝试获取锁获取锁成功返回true,失败返回false
reentrantLock.unLock();//该方法调用必须放在finally
条件变量:
可以创建多个,让某个线程进入该条件变量等待。唤醒时可以指定唤醒某个线程
Condition condition = lock.newCondition(); //创建一个条件变量,让某个线程在这里等待
Condition condition1 = lock.newCondition();
try {
condition.await(); //让线程进入等待
condition.signal(); //唤醒该条件变量中某个线程
condition.signalAll();//唤醒该条件变量中的全部线程
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
结合上面写个案例
package devise;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
*
* 小明没烟,要抽烟才能干活
* 小红饿了,要吃外卖才能干活。
* 但是在同一个房间休息小明抽烟会有烟味,小红吃不下。
* 所以分了两房间
*
*/
public class TestCorrectPostureStep {
static ReentrantLock lock=new ReentrantLock();
static Condition c1=lock.newCondition();//房间c1
static Condition c2=lock.newCondition();//房间c2
static boolean cigarette =false;
static boolean takeout =false;
public static void main(String[] args){
//小明
Thread t1=new Thread(()->{
lock.lock();
try {
while (!cigarette){
System.out.println("烟没到休息一会");
try {
c1.await(); //让小明到c1休息室休息
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("烟到了,开始干活");
} finally {
lock.unlock();
}
});
//小红
Thread t2 =new Thread(()->{
lock.lock();
try {
while (!takeout){
System.out.println("外卖没到休息一会");
try {
c2.await();//让小红到c2休息室休息
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("外卖到了,开始干活");
}finally {
lock.unlock();
}
});
//送外卖线程
Thread t3=new Thread(()->{
lock.lock();
try {
Thread.sleep(2000);
cigarette=true;
c1.signal();//唤醒小红让小明干活
} catch (InterruptedException e) {
throw new RuntimeException(e);
}finally {
lock.unlock();
}
});
//送烟线程
Thread t4=new Thread(()->{
lock.lock();
try {
Thread.sleep(2000);
takeout=true;
c2.signal(); //唤醒小明让小明干活
} catch (InterruptedException e) {
throw new RuntimeException(e);
}finally {
lock.unlock();
}
});
t1.start();
t2.start();
t3.start();
t4.start();
}}
标签:Thread,lock,ReentrantLock,try,static,线程,new
From: https://www.cnblogs.com/csm233/p/18239989