共计 2587 个字符,预计需要花费 7 分钟才能阅读完成。
一、应用
1.1 简略应用
public class LockTest {
// 新建锁
Lock lock = new ReentrantLock();
public static void main(String[] args) {
// 测试
LockTest test = new LockTest();
test.te();}
public void te(){
try {
// 获取锁
lock.lock();
System.out.println("获取到锁执行代码!");
} catch (Exception e) {e.printStackTrace();
} finally {
// 肯定留神 在 finally 中开释锁
lock.unlock();}
}
}
1.2 tryLock
Lock 比 synchronized 还是多一些性能的,比方能够设置规定工夫内获取不到锁就返回,不始终阻塞。
一个不合时宜的例子就是:
synchronize 就是一个舔狗,始终舔 直到天荒地老
lock 的 tryLock 就像是一个渣男,微微尝试一下,不适合放松下一个
public class LockTest02 {
// 新建锁
Lock lock = new ReentrantLock();
public static void main(String[] args) {
// 测试
LockTest02 test = new LockTest02();
new Thread(()->test.te()).start();
// test::teTryLock lambda 写法
new Thread(test::teTryLock).start();}
private void teTryLock() {
boolean res = false;
try {
// 尝试获取 5 秒钟获取不到就完结
res = lock.tryLock(5,TimeUnit.SECONDS);
if (res) {System.out.println("teTryLock 获取到锁了,执行获取到锁的代码");
} else{System.out.println("teTryLock 没有获取到锁 执行没有获取到锁的代码");
}
} catch (Exception e) {e.printStackTrace();
} finally {
// 如果获取到锁了 再开释
if (res) {lock.unlock();
}
}
}
public void te(){
try {
// 获取锁
lock.lock();
System.out.println("te 获取到锁执行代码!");
Thread.sleep(10000);
} catch (Exception e) {e.printStackTrace();
} finally {
// 肯定留神 在 finally 中开释锁
lock.unlock();
System.out.println("te 开释锁!");
}
}
}
输入后果:te 获取到锁执行代码!teTryLock 没有获取到锁 执行没有获取到锁的代码
te 开释锁!
1.3 lockInterruptibly
synchronized 如果开始期待是不能完结的
然而 Lock 应用 lockInterruptibly 能够被中断 在异样捕捉里捕捉异样 而后做一些后置解决
public class LockTest03 {
// 新建锁
Lock lock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
// 测试
LockTest03 test = new LockTest03();
new Thread(test::te).start();
Thread thread = new Thread(test::teLockInterruptibly);
thread.start();
Thread.sleep(3000);
thread.interrupt();}
private void teLockInterruptibly() {
boolean res = true;
try {
// 尝试获取 5 秒钟获取不到就完结
lock.lockInterruptibly();
System.out.println("获取到锁··");
} catch (InterruptedException e) {
// 没有失常获取锁 被 Interrupt 了
res = false;
System.out.println("InterruptedException: 被打断了 做一些其余解决");
} finally {
// 如果没被打断 是失常获取锁的(实践上是,也可能有其余异样)if(res) {lock.unlock();
}
}
}
public void te(){
try {
// 获取锁
lock.lock();
System.out.println("te 获取到锁执行代码!");
// te 办法睡死过来了
Thread.sleep(10000000);
} catch (Exception e) {e.printStackTrace();
} finally {
// 肯定留神 在 finally 中开释锁
lock.unlock();
System.out.println("te 开释锁!");
}
}
}
1.4 偏心锁
synchronized 是非偏心锁 起初的也可能会先获取到锁
Lock 锁默认也是非偏心锁
非偏心锁是什么样的?
用不要脸的小强来做比喻,假如有 10 集体在排队买饼,小强这时候也来买饼了,不要脸的他间接跑第一个地位,这时候如果正有人在选饼,那他就兴冲冲的走了,如果上一个人刚好买完,下一个人还没有开始选,那不要脸的小强就会趁着这个间隙间接跟老板选饼. 这样对于后边排队的是不偏心的 所以称为不偏心锁
在 ReentrantLock 的实现中,不要脸的小强会 尝试好几次,最初都失败的话他才会去队尾排队
Lock 能够实现偏心锁:偏心锁就是 lock 的时候会先去排队队列里边看看,有没有人在排队,有的话站后边去, 能够看我写过的 AQS,用偏心锁做的举例 讲到了源码层
留神:偏心锁不是齐全偏心,偏心锁只是会查看队列里有没有人排队,如果没有本人去申请锁,如果有本人去排队,去查看有没有人排队的时候可能会呈现不偏心(地铁一个人一大步窜你前边了),进队列的时候也可能会呈现不偏心(地铁一个人一大步窜你前边了)
Lock lock = new ReentrantLock(true); // true 示意偏心
有问题能够留言哦,也能够公众号留言(回复快):
正文完