补充图片

This commit is contained in:
Dragon
2020-10-19 23:10:58 +08:00
parent ed3a5abe0e
commit 36e0f0f6e0
9 changed files with 428 additions and 240 deletions

View File

@@ -1,6 +1,6 @@
> 1、文章会优先更新在Github和公总号里个人博客可能会有延迟。 > 1、文章会优先更新在Github和公总号里个人博客可能会有延迟。
> >
> 2、如果想要良好的阅读体验,可以[Github在线阅读](https://blog.youthlql.vip/JavaYouth/),或者[Gitee在线阅读](https://youthlql.gitee.io/JavaYouth)[个人博客](https://youthlql.gitee.io/)。Gitee在线阅读和个人博客加载速度比较快。 > 2、如果Github很卡,可以[Gitee](https://gitee.com/youthlql/JavaYouth)浏览,或者[Gitee在线阅读](https://youthlql.gitee.io/JavaYouth)[个人博客](https://youthlql.gitee.io/)。Gitee在线阅读和个人博客加载速度比较快。
> >
> 3、转载须知转载请注明GitHub出处让我们一起维护一个良好的技术创作环境 > 3、转载须知转载请注明GitHub出处让我们一起维护一个良好的技术创作环境
> >

View File

@@ -1,3 +1,22 @@
---
title: 详解JDK8新特性
tags:
- Java8
- JDK8
- 新特性
categories:
- Java
- 新特性
keywords: Java8新特性JDK8
description: 详解JDK8出现的新特性。
cover: 'https://cdn.jsdelivr.net/gh/youthlql/lql_img/Java_Basis/javabasis_logo.png'
top_img: 'https://cdn.jsdelivr.net/gh/youthlql/lql_img/blog/top_img.jpg'
abbrlink: de3879ae
date: 2020-10-19 22:15:58
---
# Java8新特性纵览 # Java8新特性纵览
> 本篇文章只讲解比较重要的 > 本篇文章只讲解比较重要的
@@ -1456,7 +1475,7 @@ public class SuperClass {
``` ```java
public interface CompareB { public interface CompareB {
default void method3(){ default void method3(){

View File

@@ -1,3 +1,22 @@
---
title: 详解JDK8新特性
tags:
- Java
- 基础
- 泛型
categories:
- Java
- 新特性
keywords: Java基础泛型
description: 万字长文详解Java泛型。
cover: 'https://cdn.jsdelivr.net/gh/youthlql/lql_img/Java_Basis/javabasis_logo.png'
top_img: 'https://cdn.jsdelivr.net/gh/youthlql/lql_img/blog/top_img.jpg'
abbrlink: de3879ae
date: 2020-10-19 22:21:58
---
# 简介 # 简介
## 泛型的优点 ## 泛型的优点
@@ -10,7 +29,7 @@
那么泛型的好处就是在编译的时候能够检查类型安全,并且所有的强制转换都是自动和隐式的。 那么泛型的好处就是在编译的时候能够检查类型安全,并且所有的强制转换都是自动和隐式的。
``` ```java
public class GlmapperGeneric<T> { public class GlmapperGeneric<T> {
private T t; private T t;
public void set(T t) { this.t = t; } public void set(T t) { this.t = t; }
@@ -642,7 +661,8 @@ Process finished with exit code 0
即:**如果静态方法要使用泛型的话,必须将静态方法也定义成泛型方法** 。 即:**如果静态方法要使用泛型的话,必须将静态方法也定义成泛型方法** 。
public class StaticGenerator<T> { ```java
public class StaticGenerator<T> {
/** /**
* 1、如果在类中定义使用泛型的静态方法需要添加额外的泛型声明将这个方法定义成泛型方法 * 1、如果在类中定义使用泛型的静态方法需要添加额外的泛型声明将这个方法定义成泛型方法
@@ -663,7 +683,8 @@ Process finished with exit code 0
return list; return list;
} }
} }
```
@@ -1565,7 +1586,7 @@ class keyAndDifficultPoints/principle/Test_Generic1 {
如果顺序变一下 如果顺序变一下
``` ```java
class Test_Generic1<T extends Collection & List> class Test_Generic1<T extends Collection & List>
``` ```
@@ -1573,7 +1594,7 @@ class Test_Generic1<T extends Collection & List>
T变成了Collection T变成了Collection
``` ```java
// class version 52.0 (52) // class version 52.0 (52)
// access flags 0x20 // access flags 0x20
// signature <T::Ljava/util/Collection;:Ljava/util/List;>Ljava/lang/Object; // signature <T::Ljava/util/Collection;:Ljava/util/List;>Ljava/lang/Object;
@@ -1798,7 +1819,7 @@ test4(queue);
在调用泛型方法的时候,可以指定泛型,也可以不指定泛型。在不指定泛型的情况下,泛型变量的类型为 该方法中的几种类型的同一个父类的最小级直到Object。在指定泛型的时候该方法中的几种类型必须是该泛型实例类型或者其子类。 在调用泛型方法的时候,可以指定泛型,也可以不指定泛型。在不指定泛型的情况下,泛型变量的类型为 该方法中的几种类型的同一个父类的最小级直到Object。在指定泛型的时候该方法中的几种类型必须是该泛型实例类型或者其子类。
``` ```java
class Test { class Test {
public static void main(String[] args) { public static void main(String[] args) {
//不指定泛型的时候 //不指定泛型的时候

View File

@@ -7,7 +7,7 @@ tags:
categories: categories:
- Java并发 - Java并发
keywords: Java并发原理源码 keywords: Java并发原理源码
description: Java并发体系-第一阶段-多线程基础知识,后续会陆续出更深入的 description: 万字系列长文讲解Java并发-第一阶段-多线程基础知识。
cover: 'https://cdn.jsdelivr.net/gh/youthlql/lql_img/Java_concurrency/logo_1.png' cover: 'https://cdn.jsdelivr.net/gh/youthlql/lql_img/Java_concurrency/logo_1.png'
top_img: 'https://cdn.jsdelivr.net/gh/youthlql/lql_img/blog/top_img.jpg' top_img: 'https://cdn.jsdelivr.net/gh/youthlql/lql_img/blog/top_img.jpg'
abbrlink: efc79183 abbrlink: efc79183
@@ -181,7 +181,7 @@ public class ThreadTest1 {
### Runnable接口构造线程源码 ### Runnable接口构造线程源码
``` ```java
/*下面是Thread类的部分源码*/ /*下面是Thread类的部分源码*/
//1.用Runnable接口创建线程时会进入这个方法 //1.用Runnable接口创建线程时会进入这个方法
@@ -287,7 +287,7 @@ MyThread t2 = new MyThread(); //这个构造函数会默认调用Super();也就
``` ```java
//代码从上往下顺序执行 //代码从上往下顺序执行
public Thread() { public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0); init(null, null, "Thread-" + nextThreadNum(), 0);
@@ -374,7 +374,7 @@ private void init(ThreadGroup g, Runnable target, String name,
### 最直观的代码描述 ### 最直观的代码描述
``` ```java
class Window extends Thread{ class Window extends Thread{
@@ -418,7 +418,7 @@ public class WindowTest {
``` ```java
class Window1 implements Runnable{ class Window1 implements Runnable{
private int ticket = 100; private int ticket = 100;
@@ -645,7 +645,7 @@ public void run() {
Java 线程在运行的生命周期中的指定时刻只可能处于下面 6 种不同状态的其中一个状态这几个状态在Java源码中用枚举来表示。 Java 线程在运行的生命周期中的指定时刻只可能处于下面 6 种不同状态的其中一个状态这几个状态在Java源码中用枚举来表示。
<img src="image/0005.png"> <img src="https://cdn.jsdelivr.net/gh/youthlql/lql_img/Java_concurrency/Source_code/First_stage/0005.png">
线程在生命周期中并不是固定处于某一个状态而是随着代码的执行在不同状态之间切换。Java 线程状态变迁如下图所示。 线程在生命周期中并不是固定处于某一个状态而是随着代码的执行在不同状态之间切换。Java 线程状态变迁如下图所示。
@@ -928,7 +928,7 @@ public static void main(String[] args) {
## join中断测试 ## join中断测试
``` ```java
Thread main = Thread.currentThread(); Thread main = Thread.currentThread();
Thread t2 = new Thread() { Thread t2 = new Thread() {
@Override @Override

View File

@@ -1,3 +1,21 @@
---
title: 'Java并发体系-第三阶段-JUC并发包-[1]'
tags:
- Java并发
- 原理
- 源码
categories:
- Java并发
keywords: Java并发原理源码
description: 万字系列长文讲解-Java并发体系-第三阶段-JUC并发包。JUC在高并发编程中使用频率非常高这里会详细介绍其用法。
cover: 'https://cdn.jsdelivr.net/gh/youthlql/lql_img/Java_concurrency/logo_1.png'
top_img: 'https://cdn.jsdelivr.net/gh/youthlql/lql_img/blog/top_img.jpg'
abbrlink: 5be45d9e
date: 2020-10-19 22:13:58
---
# AtomicXXXFieldUpdater # AtomicXXXFieldUpdater
> 算是一个小补充 > 算是一个小补充
@@ -1080,8 +1098,10 @@ public class Video34 {
### 构造方法 ### 构造方法
public Semaphore(int permits) ```java
public Semaphore(int permits , boolean fair) public Semaphore(int permits)
public Semaphore(int permits , boolean fair)
```
* `permits`:同一时间可以访问资源的线程数目 * `permits`:同一时间可以访问资源的线程数目
@@ -1089,16 +1109,18 @@ public class Video34 {
### 重要方法 ### 重要方法
public void acquire() throws InterruptedException ```java
public void release() public void acquire() throws InterruptedException
public void release()
```
* `acquire()`**获取一个许可证**,如果许可证用完了,则陷入阻塞。可以被打断。 * `acquire()`**获取一个许可证**,如果许可证用完了,则陷入阻塞。可以被打断。
* `release()`**释放一个许可证** * `release()`**释放一个许可证**
acquire(int permits) `acquire(int permits)`
public void release(int permits) `public void release(int permits)`
**acquire多个时如果没有足够的许可证可用那么当前线程将被禁用以进行线程调度**,并且处于休眠状态,直到发生两件事情之一: **acquire多个时如果没有足够的许可证可用那么当前线程将被禁用以进行线程调度**,并且处于休眠状态,直到发生两件事情之一:
@@ -1107,35 +1129,39 @@ public class Video34 {
**release多个时会使许可证增多最终可能超过初始值** **release多个时会使许可证增多最终可能超过初始值**
public boolean tryAcquire(int permits) ```java
public boolean tryAcquire(int permits, public boolean tryAcquire(int permits)
public boolean tryAcquire(int permits,
long timeout, long timeout,
TimeUnit unit) TimeUnit unit)
throws InterruptedException throws InterruptedException
```
* 尝试去拿,**拿到返回true** * 尝试去拿,**拿到返回true**
### 其他方法 ### 其他方法
public int availablePermits() ```java
public int availablePermits()
```
* 返回此信号量中当前可用的许可数。 * 返回此信号量中当前可用的许可数。
protected Collection<Thread> getQueuedThreads() `protected Collection<Thread> getQueuedThreads()`
public final int getQueueLength() public final int getQueueLength()
* `getQueuedThreads`返回正在阻塞的线程集合 * `getQueuedThreads`返回正在阻塞的线程集合
* `getQueueLength`返回阻塞获取的线程数 * `getQueueLength`返回阻塞获取的线程数
public void acquireUninterruptibly() `public void acquireUninterruptibly()`
public void acquireUninterruptibly(int permits) `public void acquireUninterruptibly(int permits)`
* 可以`不被打断`获取许可证 * 可以`不被打断`获取许可证
public int drainPermits() `public int drainPermits()`
* 获取当前全部的许可证目标 * 获取当前全部的许可证目标
@@ -1300,7 +1326,7 @@ C 9
## Condition版生产者消费者 ## Condition版生产者消费者
``` ```java
/** /**
* @Author: youthlql-吕 * @Author: youthlql-吕
* @Date: 2019/9/26 15:03 * @Date: 2019/9/26 15:03

View File

@@ -1,3 +1,21 @@
---
<img src="https://cdn.jsdelivr.net/gh/youthlql/lql_img/Java_concurrency/Source_code/Third_stage/0001.png">title: 'Java并发体系-第三阶段-JUC并发包-[2]'
tags:
- Java并发
- 原理
- 源码
categories:
- Java并发
keywords: Java并发原理源码
description: 万字系列长文讲解-Java并发体系-第三阶段-JUC并发包。JUC在高并发编程中使用频率非常高这里会详细介绍其用法。
cover: 'https://cdn.jsdelivr.net/gh/youthlql/lql_img/Java_concurrency/logo_1.png'
top_img: 'https://cdn.jsdelivr.net/gh/youthlql/lql_img/blog/top_img.jpg'
abbrlink: 70c90e5d
date: 2020-10-19 22:13:58
---
# Phaser工具 # Phaser工具
@@ -286,8 +304,10 @@ public class test {
### 注册 ### 注册
public int register() ```java
public int bulkRegister(int parties) public int register()
public int bulkRegister(int parties)
```
**register** **register**
@@ -300,9 +320,11 @@ public class test {
### 到达 ### 到达
public int arrive() ```java
public int arriveAndDeregister() public int arrive()
public int arriveAndAwaitAdvance() public int arriveAndDeregister()
public int arriveAndAwaitAdvance()
```
**arrive** **arrive**
@@ -319,7 +341,8 @@ public class test {
**举例** **举例**
public class PhaserTest { ```java
public class PhaserTest {
private static final Random RANDOM = new Random(); private static final Random RANDOM = new Random();
@@ -365,7 +388,8 @@ public class test {
} }
} }
} }
```
### onAdvance() ### onAdvance()
@@ -387,8 +411,10 @@ protected boolean onAdvance(int phase, int registeredParties) {
### 监控子线程任务 ### 监控子线程任务
public int awaitAdvance(int phase) ```java
public int awaitAdvanceInterruptibly(int phase) throws InterruptedException public int awaitAdvance(int phase)
public int awaitAdvanceInterruptibly(int phase) throws InterruptedException
```
* 相当于起到监控的作用 * 相当于起到监控的作用
@@ -397,7 +423,8 @@ protected boolean onAdvance(int phase, int registeredParties) {
**举例** **举例**
public static void main(String[] args) throws InterruptedException { ```java
public static void main(String[] args) throws InterruptedException {
final Phaser phaser = new Phaser(4); final Phaser phaser = new Phaser(4);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
@@ -406,13 +433,16 @@ protected boolean onAdvance(int phase, int registeredParties) {
//等待全部任务进行完成 //等待全部任务进行完成
phaser.awaitAdvance(phaser.getPhase()); phaser.awaitAdvance(phaser.getPhase());
System.out.println("The phase 1 work finish done."); System.out.println("The phase 1 work finish done.");
} }
```
### 强制关闭 ### 强制关闭
public void forceTermination() ```java
public boolean isTerminated() public void forceTermination()
public boolean isTerminated()
```
* 强制关闭phaser但是`如果线程陷入阻塞,不会唤醒` * 强制关闭phaser但是`如果线程陷入阻塞,不会唤醒`
@@ -422,7 +452,9 @@ protected boolean onAdvance(int phase, int registeredParties) {
### 获取阶段数 ### 获取阶段数
public final int getPhase() ```java
public final int getPhase()
```
* 返回当前相位数。 最大相位数为Integer.MAX_VALUE * 返回当前相位数。 最大相位数为Integer.MAX_VALUE
@@ -430,7 +462,8 @@ protected boolean onAdvance(int phase, int registeredParties) {
**举例** **举例**
public class PhaserTest { ```java
public class PhaserTest {
public static void main(String[] args) { public static void main(String[] args) {
final Phaser phaser = new Phaser(1); final Phaser phaser = new Phaser(1);
System.out.println(phaser.getPhase()); System.out.println(phaser.getPhase());
@@ -445,7 +478,8 @@ protected boolean onAdvance(int phase, int registeredParties) {
System.out.println(phaser.getPhase()); System.out.println(phaser.getPhase());
} }
} }
```
**结果** **结果**
@@ -458,7 +492,9 @@ protected boolean onAdvance(int phase, int registeredParties) {
### 获取注册的数 ### 获取注册的数
public int getRegisteredParties() ```java
public int getRegisteredParties()
```
* 获得注册的线程数相当于Countdown初始的的计数器 * 获得注册的线程数相当于Countdown初始的的计数器
@@ -466,8 +502,10 @@ protected boolean onAdvance(int phase, int registeredParties) {
### 获得到达和未到达的数目 ### 获得到达和未到达的数目
public int getArrivedParties() ```java
public int getUnarrivedParties() public int getArrivedParties()
public int getUnarrivedParties()
```
**getArrivedParties** **getArrivedParties**
@@ -488,6 +526,7 @@ protected boolean onAdvance(int phase, int registeredParties) {
Phaser 内部用一个 `state` 来管理状态变化,随着 parties 的增加,并发问题带来的性能影响会越来越严重。 Phaser 内部用一个 `state` 来管理状态变化,随着 parties 的增加,并发问题带来的性能影响会越来越严重。
```java
/** /**
* 0-15: unarrived * 0-15: unarrived
* 16-31: parties 所以一个 phaser 实例最大支持 2^16-1=65535 个 parties * 16-31: parties 所以一个 phaser 实例最大支持 2^16-1=65535 个 parties
@@ -495,6 +534,7 @@ protected boolean onAdvance(int phase, int registeredParties) {
* 63: terminated * 63: terminated
*/ */
private volatile long state; private volatile long state;
```
> 通常我们在说 0-15 位这种,说的都是从低位开始的 > 通常我们在说 0-15 位这种,说的都是从低位开始的
@@ -507,6 +547,7 @@ protected boolean onAdvance(int phase, int registeredParties) {
这里我们不讲源码,用通俗一点的语言表述一下。我们先写段代码构造一棵树: 这里我们不讲源码,用通俗一点的语言表述一下。我们先写段代码构造一棵树:
```java
Phaser root = new Phaser(5); Phaser root = new Phaser(5);
Phaser n1 = new Phaser(root, 5); Phaser n1 = new Phaser(root, 5);
@@ -517,11 +558,12 @@ protected boolean onAdvance(int phase, int registeredParties) {
Phaser m3 = new Phaser(n1, 5); Phaser m3 = new Phaser(n1, 5);
Phaser m4 = new Phaser(n2, 5); Phaser m4 = new Phaser(n2, 5);
```
根据上面的代码,我们可以画出下面这个很简单的图: 根据上面的代码,我们可以画出下面这个很简单的图:
![phaser](image/0002.png) <img src="https://cdn.jsdelivr.net/gh/youthlql/lql_img/Java_concurrency/Source_code/Third_stage/0002.png">
这棵树上有 7 个 phaser 实例,每个 phaser 实例在构造的时候,都指定了 parties 为 5但是对于每个拥有子节点的节点来说每个子节点都是它的一个 party我们可以通过 phaser.getRegisteredParties() 得到每个节点的 parties 数量: 这棵树上有 7 个 phaser 实例,每个 phaser 实例在构造的时候,都指定了 parties 为 5但是对于每个拥有子节点的节点来说每个子节点都是它的一个 party我们可以通过 phaser.getRegisteredParties() 得到每个节点的 parties 数量:
@@ -535,18 +577,22 @@ protected boolean onAdvance(int phase, int registeredParties) {
在上面代码的基础上,大家可以试一下下面的这个代码: 在上面代码的基础上,大家可以试一下下面的这个代码:
```java
Phaser m5 = new Phaser(n2); Phaser m5 = new Phaser(n2);
System.out.println("n2 parties: " + n2.getRegisteredParties()); System.out.println("n2 parties: " + n2.getRegisteredParties());
m5.register(); m5.register();
System.out.println("n2 parties: " + n2.getRegisteredParties()); System.out.println("n2 parties: " + n2.getRegisteredParties());
```
第一行代码中构造了 m5 实例,但是此时它的 parties == 0所以对于父节点 n2 来说,它的 parties 依然是 6所以第二行代码输出 6。第三行代码注册了 m5 的第一个 party显然第四行代码会输出 7。 第一行代码中构造了 m5 实例,但是此时它的 parties == 0所以对于父节点 n2 来说,它的 parties 依然是 6所以第二行代码输出 6。第三行代码注册了 m5 的第一个 party显然第四行代码会输出 7。
当子节点的 parties 降为 0 的时候,会从父节点中"剥离",我们在上面的基础上,再加两行代码: 当子节点的 parties 降为 0 的时候,会从父节点中"剥离",我们在上面的基础上,再加两行代码:
```java
m5.arriveAndDeregister(); m5.arriveAndDeregister();
System.out.println("n2 parties: " + n2.getRegisteredParties()); System.out.println("n2 parties: " + n2.getRegisteredParties());
```
由于 m5 之前只有一个 parties所以一次 arriveAndDeregister() 就会使得它的 parties 变为 0此时第二行代码输出父节点 n2 的 parties 为 6。 由于 m5 之前只有一个 parties所以一次 arriveAndDeregister() 就会使得它的 parties 变为 0此时第二行代码输出父节点 n2 的 parties 为 6。
@@ -1211,16 +1257,19 @@ public static ExecutorService newWorkStealingPool() {
## newScheduledThreadPool ## newScheduledThreadPool
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { ```java
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize); return new ScheduledThreadPoolExecutor(corePoolSize);
} }
```
* 创建的是一个定时的任务,每隔一段时间就会运行一次 * 创建的是一个定时的任务,每隔一段时间就会运行一次
**首先可以对比的就是Timer这个类** **首先可以对比的就是Timer这个类**
public class ExecutorsTest { ```java
public class ExecutorsTest {
public static void main(String[] args) throws InterruptedException { public static void main(String[] args) throws InterruptedException {
Timer timer = new Timer(); Timer timer = new Timer();
@@ -1238,7 +1287,8 @@ public static ExecutorService newWorkStealingPool() {
//1秒执行一次 //1秒执行一次
timer.schedule(task,0,1000); timer.schedule(task,0,1000);
} }
} }
```
**结果** **结果**
@@ -1269,7 +1319,7 @@ public static ExecutorService newWorkStealingPool() {
# ExecutorService # ExecutorService
``` ```java
public class Video53 { public class Video53 {
public static void main(String[] args) { public static void main(String[] args) {
ExecutorService threadPool = new ThreadPoolExecutor( ExecutorService threadPool = new ThreadPoolExecutor(
@@ -1602,7 +1652,7 @@ public class ExecutorCompletionService<V> implements CompletionService<V> {
**执行流程:** **执行流程:**
![image-20200914182032618](image/0004.png) <img src="https://cdn.jsdelivr.net/gh/youthlql/lql_img/Java_concurrency/Source_code/Third_stage/0004.png">
@@ -2258,12 +2308,14 @@ public class Test_Accept {
### 组合两个任务,任务完成后做的操作 ### 组合两个任务,任务完成后做的操作
public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other, ```java
public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,
Runnable action) Runnable action)
public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other, public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other,
Runnable action) Runnable action)
public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other, public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other,
Runnable action) Runnable action)
```
@@ -2317,12 +2369,14 @@ public class Test_runAfterEither {
### 组合两个任务,处理后,返回一个结果 ### 组合两个任务,处理后,返回一个结果
public <U,V> CompletableFuture<V> thenCombine(CompletionStage<? extends U> other, ```java
public <U,V> CompletableFuture<V> thenCombine(CompletionStage<? extends U> other,
BiFunction<? super T,? super U,? extends V> fn) BiFunction<? super T,? super U,? extends V> fn)
public <U,V> CompletableFuture<V> thenCombineAsync(CompletionStage<? extends U> other, public <U,V> CompletableFuture<V> thenCombineAsync(CompletionStage<? extends U> other,
BiFunction<? super T,? super U,? extends V> fn) BiFunction<? super T,? super U,? extends V> fn)
public <U,V> CompletableFuture<V> thenCombineAsync(CompletionStage<? extends U> other, public <U,V> CompletableFuture<V> thenCombineAsync(CompletionStage<? extends U> other,
BiFunction<? super T,? super U,? extends V> fn,, Executor executor) BiFunction<? super T,? super U,? extends V> fn,, Executor executor)
```
@@ -2402,9 +2456,11 @@ Process finished with exit code 0
#### 当执行完成时执行的操作 #### 当执行完成时执行的操作
public CompletableFuture<T> whenComplete(BiConsumer<? super T,? super Throwable> action) ```java
public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T,? super Throwable> action) public CompletableFuture<T> whenComplete(BiConsumer<? super T,? super Throwable> action)
public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T,? super Throwable> action, Executor executor) public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T,? super Throwable> action)
public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T,? super Throwable> action, Executor executor)
```
**举例** **举例**
@@ -2459,7 +2515,7 @@ public class Test_whenComplete {
public interface BiConsumer<T, U> { public interface BiConsumer<T, U> {
void accept(T t, U u); void accept(T t, U u);
``` ```
@@ -2469,9 +2525,11 @@ public class Test_whenComplete {
#### 级联操作 #### 级联操作
public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn) ```java
public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn) public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn)
public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn,Executor executor) public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn)
public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn,Executor executor)
```
**举例** **举例**
@@ -2520,14 +2578,17 @@ public interface Function<T, R> {
#### 处理结果的操作 #### 处理结果的操作
public <U> CompletableFuture<U> handle(BiFunction<? super T,Throwable,? extends U> fn) ```java
public <U> CompletableFuture<U> handleAsync(BiFunction<? super T,Throwable,? extends U> fn) public <U> CompletableFuture<U> handle(BiFunction<? super T,Throwable,? extends U> fn)
public <U> CompletableFuture<U> handleAsync(BiFunction<? super T,Throwable,? extends U> fn,Executor executor) public <U> CompletableFuture<U> handleAsync(BiFunction<? super T,Throwable,? extends U> fn)
public <U> CompletableFuture<U> handleAsync(BiFunction<? super T,Throwable,? extends U> fn,Executor executor)
```
**举例** **举例**
public class CompletableFutureTest { ```java
public class CompletableFutureTest {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello"); CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello");
@@ -2541,7 +2602,8 @@ public interface Function<T, R> {
Thread.currentThread().join(); Thread.currentThread().join();
} }
} }
```
**结果** **结果**
@@ -2561,14 +2623,17 @@ public interface Function<T, R> {
#### 处理结果 #### 处理结果
public CompletableFuture<Void> thenAccept(Consumer<? super T> action) ```java
public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action) public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action,Executor executor) public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action)
public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action,Executor executor)
```
**举例** **举例**
public class CompletableFutureTest { ```java
public class CompletableFutureTest {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello"); CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "Hello");
@@ -2581,7 +2646,8 @@ public interface Function<T, R> {
Thread.currentThread().join(); Thread.currentThread().join();
} }
} }
```
**结果** **结果**
@@ -2645,8 +2711,9 @@ Process finished with exit code -1
#### 立马获取结果 #### 立马获取结果
public T getNow(T valueIfAbsent) ```java
public T getNow(T valueIfAbsent)
```
**举例** **举例**

View File

@@ -1,3 +1,22 @@
---
title: 'Java并发体系-第二阶段-锁与同步-[1]'
tags:
- Java并发
- 原理
- 源码
categories:
- Java并发
keywords: Java并发原理源码
description: '万字系列长文讲解-Java并发体系-第二阶段,从C++和硬件方面讲解。'
cover: 'https://cdn.jsdelivr.net/gh/youthlql/lql_img/Java_concurrency/logo_1.png'
top_img: 'https://cdn.jsdelivr.net/gh/youthlql/lql_img/blog/top_img.jpg'
abbrlink: 230c5bb3
date: 2020-10-19 22:09:58
---
> - 本阶段文章讲的略微深入,一些基础性问题不会讲解,如有基础性问题不懂,可自行查看我前面的文章,或者自行学习。 > - 本阶段文章讲的略微深入,一些基础性问题不会讲解,如有基础性问题不懂,可自行查看我前面的文章,或者自行学习。
> - 本篇文章比较适合校招和社招的面试笔者在2020年面试的过程中也确实被问到了下面的一些问题。 > - 本篇文章比较适合校招和社招的面试笔者在2020年面试的过程中也确实被问到了下面的一些问题。
@@ -165,7 +184,7 @@ jcstress是java并发压测工具。https://wiki.openjdk.java.net/display/CodeTo
``` ```java
import org.openjdk.jcstress.annotations.*; import org.openjdk.jcstress.annotations.*;
import org.openjdk.jcstress.infra.results.I_Result; import org.openjdk.jcstress.infra.results.I_Result;
@@ -576,7 +595,7 @@ volatile不保证原子性只保证可见性和禁止指令重排
``` ```java
private static volatile SingletonDemo instance = null; private static volatile SingletonDemo instance = null;
private SingletonDemo() { private SingletonDemo() {

View File

@@ -1,3 +1,21 @@
---
title: 'Java并发体系-第二阶段-锁与同步-[2]'
tags:
- Java并发
- 原理
- 源码
categories:
- Java并发
keywords: Java并发原理源码
description: '万字系列长文讲解-Java并发体系-第二阶段,从C++和硬件方面讲解。'
cover: 'https://cdn.jsdelivr.net/gh/youthlql/lql_img/Java_concurrency/logo_1.png'
top_img: 'https://cdn.jsdelivr.net/gh/youthlql/lql_img/blog/top_img.jpg'
abbrlink: '8210870'
date: 2020-10-19 22:10:58
---
# 可见性设计的硬件 # 可见性设计的硬件
<img src="https://cdn.jsdelivr.net/gh/youthlql/lql_img/Java_concurrency/Source_code/Second_stage/0016.png"> <img src="https://cdn.jsdelivr.net/gh/youthlql/lql_img/Java_concurrency/Source_code/Second_stage/0016.png">
@@ -64,7 +82,7 @@ isRunning = false; => 写volatile变量就会通过执行一个内存屏障
内存屏障是被插入两个CPU指令之间的一种指令用来禁止处理器指令发生重排序像屏障一样从而保障有序性的。另外为了达到屏障的效果它也会使处理器写入、读取值之前将写缓冲器的值写入高速缓存清空无效队列实现可见性。 内存屏障是被插入两个CPU指令之间的一种指令用来禁止处理器指令发生重排序像屏障一样从而保障有序性的。另外为了达到屏障的效果它也会使处理器写入、读取值之前将写缓冲器的值写入高速缓存清空无效队列实现可见性。
举例:将写缓冲器数据写入高速缓存,能够避免不同处理器之间不能访问写缓冲器而导致的可见性问题,以及有效地避免了存储转发问题;清空无效队列保证该处理器上高速缓存中不存在旧的副本,进而拿到最新数据 举例:将写缓冲器数据写入高速缓存,能够避免不同处理器之间不能访问写缓冲器而导致的可见性问题,以及有效地避免了存储转发问题;清空无效队列保证该处理器上高速缓存中不存在旧的副本,进而拿到最新数据
## 基本内存屏障 ## 基本内存屏障

View File

@@ -1,3 +1,21 @@
---
title: 'Java并发体系-第二阶段-锁与同步-[3]'
tags:
- Java并发
- 原理
- 源码
categories:
- Java并发
keywords: Java并发原理源码
description: '万字系列长文讲解-Java并发体系-第二阶段,从C++和硬件方面讲解。'
cover: 'https://cdn.jsdelivr.net/gh/youthlql/lql_img/Java_concurrency/logo_1.png'
top_img: 'https://cdn.jsdelivr.net/gh/youthlql/lql_img/blog/top_img.jpg'
abbrlink: 113a3931
date: 2020-10-19 22:10:58
---
# synchronized保证三大特性 # synchronized保证三大特性
**synchronized保证原子性的原理** **synchronized保证原子性的原理**
@@ -75,7 +93,7 @@ synchronized的锁对象中有一个计数器recursions变量会记录线
### synchronized不可中断演示 ### synchronized不可中断演示
``` ```java
public class Test { public class Test {
private static Object obj = new Object(); private static Object obj = new Object();
public static void main(String[] args) throws InterruptedException { public static void main(String[] args) throws InterruptedException {
@@ -243,7 +261,7 @@ public class SyncTest {
使用javap对其进行反汇编部分信息如下 使用javap对其进行反汇编部分信息如下
``` ```java
{ {
public void syncBlock(); public void syncBlock();
descriptor: ()V descriptor: ()V
@@ -407,7 +425,7 @@ Mark Word用于存储对象自身的运行时数据如哈希码HashCode
## 查看Java对象布局的方法 ## 查看Java对象布局的方法
``` ```java
<dependency> <dependency>
<groupId>org.openjdk.jol</groupId> <groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId> <artifactId>jol-core</artifactId>
@@ -544,7 +562,7 @@ case 3当其他线程进入同步块时发现已经有偏向的线程了
我们看个demo在该demo中重复3次获得锁。 我们看个demo在该demo中重复3次获得锁。
``` ```java
synchronized(obj){ synchronized(obj){
synchronized(obj){ synchronized(obj){
synchronized(obj){ synchronized(obj){