| 傻瓜源码-内容简介 |
|---|
|
【职场经验】(持续更新) 如何日常学习、如何书写简历、引导面试官、系统准备面试、选择offer、提高绩效、晋升TeamLeader..... |
| 【源码解读】(持续更新)<br/> 1. 源码选材:Java架构师必须掌握的所有框架和类库源码 <br/> 2. 内容大纲:按照“企业应用Demo”讲解执行源码:总纲“阅读指南”、第一章“源码基础”、第二章“相关Java基础”、第三章“白话讲源码”、第四章“代码解读”、第五章“设计模式”、第六章“附录-面试习题、相关JDK方法、中文注释可运行源码项目” 3. 读后问题:粉丝群答疑解惑 |
| 已收录: HashMap 、 ReentrantLock 、 ThreadPoolExecutor 、 《Spring源码解读》 、 《Dubbo源码解读》 ..... |
| 【面试题集】(持续更新)<br/>1. 面试题选材:Java面试常问的所有面试题和必会知识点<br/>2. 内容大纲:第一部分”注意事项“、第二部分“面试题解读”(包括:”面试题“、”答案“、”答案详解“、“实际开发解说”) 3. 深度/广度:面试题集中的答案和答案详解,都是对齐一般面试要求的深度和广度 4. 读后问题:粉丝群答疑解惑 |
| 已收录: Java基础面试题集 、 Java并发面试题集 、 JVM面试题集 、 数据库(Mysql)面试题集 、 缓存(Redis)面试题集 ..... |
| 【粉丝群】(持续更新) <br/> 收录:阿里、字节跳动、京东、小米、美团、哔哩哔哩等大厂内推 |
| :stuck_out_tongue: 作者介绍:Spring系源码贡献者、世界五百强互联网公司、TeamLeader、Github开源产品作者 :stuck_out_tongue: 作者微信:wowangle03 (企业内推联系我) |
本文建议分为两个学习阶段,掌握了第一阶段,再进行第二阶段;
源码项目中的注释含义
LinkedBlockingQueue 是一个基于单向链表的、FIFO(先进先出)的阻塞队列。API 如下:
向队列中添加元素:
移除并返回队列头部元素:
移除队列头部元素:
获取队列头部元素:
public static void main(String[] args) throws InterruptedException {
LinkedBlockingQueue linkedBlockingQueue = new LinkedBlockingQueue<>();
linkedBlockingQueue.put("元素1");
linkedBlockingQueue.offer("元素2", 10L, TimeUnit.SECONDS);
// 移除并返回队列头部元素;如果 linkedBlockingQueue 中不存在元素,则阻塞;
// 打印结果:元素1
System.out.println(linkedBlockingQueue.take());
// 移除并返回队列头部元素;如果 linkedBlockingQueue 中不存在元素,则阻塞 10 秒钟;10秒钟后,如果仍然没有数据可取,则返回 null
// 打印结果:元素2
System.out.println(linkedBlockingQueue.poll(10L, TimeUnit.SECONDS));// 元素2
}
LinkedBlockingQueue 的内部类 Node,用来装载添加元素的,同时也是队列的组成元素。
static class Node<E> {
// item 表示当前节点存储的元素值,例如:"元素1"
E item;
// next 指向后一个 Node 节点对象(代表后一个进入队列的元素,例:"元素2")
Node<E> next;
}
public class LinkedBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable {
// head 记录头节点 Node 对象,头节点 Node 对象不装载任何数据,即 item 值为空;
// 当要调用 take() 等出队方法时,会将第二个节点的 item 值取出作为返回值,然后将 item 置为空,替换为头节点。
transient Node<E> head;
// last 记录尾节点对象
private transient Node<E> last;
// count 记录 LinkedBlockingQueue 中的 Node 数量
private final AtomicInteger count = new AtomicInteger();
// capacity 表示 LinkedBlockingQueue 最大可容纳的 Node 数,默认是 Integer 的最大值
private final int capacity;
ReentrantLock 是 JDK 并发包(java.util.concurrent)中的可重入锁(可重入锁就是指持有锁的线程可以重复进入有该锁的代码块)。详见“ReentrantLock 源码解读”。
@Test
public void testReentrantLock1() {
// 多个线程使用同一个 ReentrantLock 对象,上同一把锁
Lock lock = new ReentrantLock();
try {
// 本线程尝试获取锁;如果锁已经被其它线程持有,则会进入阻塞状态,直到获取到锁
lock.lock();
System.out.println("处理中...");
} finally {
// 释放锁
lock.unlock();
}
}
实现等待/通知机制,必须在 ReentrantLock 锁定的代码块中才能使用;与 Object 的 wait/notify 功能相似,但是支持更多功能。
public static void main(String[] args) {
// 多个线程上同一把锁
Lock reentrantLock = new ReentrantLock();
Condition condition = reentrantLock.newCondition();
// 开启一个线程
new Thread(() -> {
try {
System.out.println("线程1-lock");
reentrantLock.lock();
Thread.sleep(1000);
System.out.println("线程1-await");
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
reentrantLock.unlock();
System.out.println("线程1-unlock");
}
}).start();
// 开启另一个线程
new Thread(() -> {
try {
System.out.println("线程2-lock");
reentrantLock.lock();
System.out.println("线程2-signal");
condition.signal();
} finally {
reentrantLock.unlock();
System.out.println("线程2-unlock");
}
}).start();
}
打印结果:
线程1-lock
线程2-lock
线程1-await
线程2-signal
线程2-unlock
线程1-unlock
通过原子操作,实现线程安全的数值加减操作。
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(100);
// 获取 AtomicInteger 的值,并累加 1,最后返回加 1 前的值。
int b = atomicInteger.getAndIncrement();
// 打印结果:100
System.out.println(b);
}
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger(100);
// 获取 AtomicInteger 的值,并累加 1,最后返回加 1 后的值。
int b = atomicInteger.incrementAndGet();
// 打印结果:101
System.out.println(b);
}
<br/>
从学习到面试,从面试到工作,从 coder 到 TeamLeader,每天给你答疑解惑,还能有第二份收入,这样的知识星球,难道你还要犹豫!