可重入锁(递归锁)
LockSupport出现之前
Object类的wait,notify,notifyAll必须在synchronized内部执行
Lock的Condition的await,signal,signalAll必须和lock,unlock搭配使用
LockSupport-线程等待唤醒机制加强版
unpark获取凭证最多为1,连续调用两次unpark和调用一次的效果一样,只会增加一个凭证;而调用两次park却需要消耗两个凭证,会阻塞.
package Juc;
import java.util.concurrent.locks.LockSupport;
/**
* @ClassName LockSupportDemo
* @Description TODO
* @Author liyulong
* @Date 2021/12/3 22:09
* @Version 1.0
**/
public class LockSupportDemo {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "\t.....come in");
LockSupport.park();
System.out.println(Thread.currentThread().getName() + "\t.....被唤醒了");
}, "t1");
t1.start();
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread t2 = new Thread(() -> {
LockSupport.unpark(t1);
System.out.println(Thread.currentThread().getName() + "\t.....通知了");
}, "t1");
t2.start();
}
}
- 解决synchronized和Lock先唤醒后等待报错问题
package Juc;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
/**
* @ClassName LockSupportDemo
* @Description TODO
* @Author liyulong
* @Date 2021/12/3 22:09
* @Version 1.0
**/
public class LockSupportDemo {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "\t.....come in");
LockSupport.park();
System.out.println(Thread.currentThread().getName() + "\t.....被唤醒了");
}, "t1");
t1.start();
Thread t2 = new Thread(() -> {
LockSupport.unpark(t1);
System.out.println(Thread.currentThread().getName() + "\t.....通知了");
}, "t1");
t2.start();
}
}
AQS(AbstractQueuedSynchronizer)-JUC基石
字面意思
抽象的队列同步器
原理
如果共享资源被占用,就需要一定的阻塞等待唤醒机制来保证锁分配.这个机制主要用的是CLH队列的变体实现,将暂时获取不到锁的线程加入到队列中,这个队列就是AQS的抽象表现.它将请求共享资源的线程封装成队列的节点(Node),通过CAS,自旋,以及LockSupport.park()的方式,维护state变量的状态,使并发达到同步的控制效果.
Java技术之AQS详解
AQS详解(面试)