先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
正文
private volatile int state;
当这个state==0时,表示锁是空闲的,大于零表示锁已经被占用, 它的数值表示当前线程重复占用这个锁的次数。因此,lock()的最简单的实现是:
final void lock() {
// compareAndSetState就是对state进行CAS操作,如果修改成功就占用锁
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
//如果修改不成功,说明别的线程已经使用了这个锁,那么就可能需要等待
acquire(1);
}
下面是acquire() 的实现:
public final void acquire(int arg) {
//tryAcquire() 再次尝试获取锁,
//如果发现锁就是当前线程占用的,则更新state,表示重复占用的次数,
//同时宣布获得所成功,这正是重入的关键所在
if (!tryAcquire(arg) &&
// 如果获取失败,那么就在这里入队等待
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
//如果在等待过程中 被中断了,那么重新把中断标志位设置上
selfInterrupt();
}
公平锁和非公平锁区别
//非公平锁
final void lock() {
//上来不管三七二十一,直接抢了再说
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
//抢不到,就进队列慢慢等着
acquire(1);
}
//公平锁
final void lock() {
//直接进队列等着
acquire(1);
}
非公平锁如果第一次争抢失败,后面的处理和公平锁是一样的,都是进入等待队列慢慢等。
3.Condition
概述
Condition接口可以理解为重入锁的伴生对象。它提供了在重入锁的基础上,进行等待和通知的机制。可以使用 newCondition()方法生成一个Condition对象。
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
应用场景
在ArrayBlockingQueue阻塞队列中,就维护一个Condition对象
lock = new ReentrantLock(fair);
notEmpty = lock.newCondition();
这个notEmpty 就是一个Condition对象。它用来通知其他线程,ArrayBlockingQueue是不是空着的。当我们需要拿出一个元素时:
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
while (count == 0)
// 如果队列长度为0,那么就在notEmpty condition上等待了,一直等到有元素进来为止
// 注意,await()方法,一定是要先获得condition伴生的那个lock,才能用的哦
notEmpty.await();
//一旦有人通知我队列里有东西了,我就弹出一个返回
return dequeue();
} finally {
lock.unlock();
}
}
当有元素入队时:
public boolean offer(E e) {
checkNotNull(e);
final ReentrantLock lock = this.lock;
//先拿到锁,拿到锁才能操作对应的Condition对象
lock.lock();
try {
if (count == items.length)
return false;
else {
//入队了, 在这个函数里,就会进行notEmpty的通知,通知相关线程,有数据准备好了
enqueue(e);
return true;
}
} finally {
//释放锁了,等着的那个线程,现在可以去弹出一个元素试试了
lock.unlock();
}
}
private void enqueue(E x) {
final Object[] items = this.items;
items[putIndex] = x;
if (++putIndex == items.length)
putIndex = 0;
count++;
//元素已经放好了,通知那个等着拿东西的人吧
notEmpty.signal();
}
4.LockSupport类
LockSupport可以理解为一个工具类。它的作用很简单,就是挂起和继续执行线程。它的常用的API如下:
public static void park() : 如果没有可用许可,则挂起当前线程
public static void unpark(Thread thread):给thread一个可用的许