目录

Life in Flow

知不知,尚矣;不知知,病矣。
不知不知,殆矣。

Future、Callable

Runnable 缺陷 不能返回一个返回值 run() 方法中不能抛出 checked Exception (方法签名),只能在 run() 方法中使用 try/catch 进行异常捕获。 public abstract void run(); Callable 接口 类似于 Runnable,被其他线程执行的任务 实现 call 方法 有返回值 Future  Future 的核心思想是:一个方法的计算过程可能非常耗时,一直在原地等待方法返回,显然不明智。可以把该计算过程放到线程池去执行,并通过 Future 去控制方法的计算过程,在计算出结果后直接获取该结果。 Callable 和 Future 的关系 Future.get() 来获取 Callable 接口返回的执行结果,Future.isDone()来判断任务是否已经执行完了,以及取消这个任务,限时获取任务的结果等。 在 call() 未执行完毕之前,调用 get() 的线程(假设是主线程)会被阻塞,直到 call() 方法返回了结果后,此时 future.get() 才会得到该结果,然后主线程 CIA 会切换到 ....

AbstractQueuedSynchronizer

AQS 的作用  ReentrantLock、Semaphore、CountDownLatch、ReentrantReadWriteLock 等类具有的 协作(同步)功能,底层都是一个共同的基类 AQS。  AQS 是一个用于构建锁、同步器、协作工具类的工具类(框架)。有了 AQS 以后,更多的协作工具类都可以很方便得被编写出来。  一句话总结:有了 AQS,构建线程协作类就容易多了。 Semaphore 和 AQS 的关系  Semaphore 内部有一个 Sync 类, Sync 类继承了 AQS。 如果没有 AQS 每个协作工具自己实现一些功能:(这些功能都是通用的) * 同步状态的原子性管理(例如:CountDownLatch 计数器) * 线程的阻塞与解除阻塞 * 队列的管理 在并发场景下,自己正确且高效实现这些内容,是相当有难度的,所以我们用 AQS 来帮我们把这些脏活累活都搞定,我们只关注业务逻辑就行了。甚至我们可以利用 AQS 自定义一个线程协作类。 AQS 的重要性、地位  AbstactQueuedSynchronizer 是 Doug Lea 写的,从....

SDKMAN

SDKMAN简介  JDK版本迭代太快,多个版本手动改 JAVA_HOME 太痛苦。 安装 SDKMAN windows 安装需要 bash, zip, unzip, curl。 包含关系: chocolatey(Windows的包管理工具) - zip - unzip git bash(Windows的git终端) - bash - curl C:\> choco install unzip C:\> choco install zip # 安装Git # 打开 Git bash 终端,执行命令: curl -s "https://get.sdkman.io" | bash [root@master ~]# sdk ls java ================================================================================ Available Java Versions ==================================================================....

Java 的基本类型

AsmTools  在 OpenJDK 里有一个 AsmTools 项目,用来生成正确的或者不正确的 Java .class 文件,主要用来测试和验证。我们知道直接修改.class文件是很麻烦的,虽然有一些图形界面的工具,但还是很麻烦。  AsmTools 引入了两种表示 .class 文件的语法: JASM 用类似 Java 本身的语法来定义类和函数,字节码指令则很像传统的汇编。 java -jar asmtools.jar jdis Test.class JCOD 整个 .class 用容器的方式来表示,可以很清楚表示类文件的结构。 java -jar asmtools.jar jdec Test.class AsmTools修改字节码 Java源码文件 public class Foo { public static void main(String[] args) { boolean flag = true; if (flag) System.out.println("Hello, Java!"); if (flag == true) System.out.prin....

Java 代码运行流程

编译执行  直接将代码编译成 CPU 所能理解的代码格式,机器码。  比如下图的中间列,就是用 C 语言写的 Helloworld 程序的编译结果。可以看到,C 程序编译而成的机器码就是一个个的字节,它们是给机器读的。那么为了让开发人员也能够理解,我们可以用反汇编器将其转换成汇编代码(如下图的最右列所示)。 ; 最左列是偏移;中间列是给机器读的机器码;最右列是给人读的汇编代码 0x00: 55 push rbp 0x01: 48 89 e5 mov rbp,rsp 0x04: 48 83 ec 10 sub rsp,0x10 0x08: 48 8d 3d 3b 00 00 00 lea rdi,[rip+0x3b] ; 加载 "Hello, World!\n" 0x0f: c7 45 fc 00 00 00 00 mov DWORD PTR [rbp-0x4],0x0 0x16: b0 00 mov al,0x0 0x18: e8 0d 00 00 00 call 0x12 ; 调用 printf 方法 0x1d: 31 c9 xor ecx,ecx 0x1f: 89 45 f8 mo....

控制并发流程的工具类

什么是控制并发流程?  控制并发流程的工具类,作用就是帮助开发者更容易得让线程之间合作。  让线程之间相互配合,来满足业务逻辑(按照预想的方式并发执行)。 比如:让线程 A 等待线程 B 执行完毕再执行等合作策略。 控制并发流程工具类纵览 CountDownLatch  直译 倒数门栓,类似于过山车,人满才会发车。  执行流程如下: 1. 线程开始运行 2. 进入等待,倒数结束之前,一直处于`等待`状态 3. 等待的过程中进行倒数(减) 4. 倒数结束,线程`继续`工作。 CountDownLatch 主要方法概览 * CountDownLatch(int count):仅有一个构造函数,参数 count 为需要倒数的数值。 * await():调用 await() 方法的线程会被挂起,它会等待直到 count 值为 0 才继续执行。 * countDown():将 count 值减1,直到为0时,等待的线程会被唤醒。 CountDownLatch 用法 * 一个线程等待多个线程都执行完毕,再继续自己的工作。 一等多 * 多个线程等待某个线程的信号,同时开始执行。 多等一 *....

Concurrent Container

Vector、Hashtable Vector 特点  类似一个线程安全的 ArrayList * 大量容器操作方法都采用同步方法 Vector<String> vector = new Vector<>(); vector.add("test"); System.out.println(vector.get(0)); Hashtable 特点  类似一个线程安全的 HashMap * 大量容器操作方法都采用同步方法 Hashtable<String, String> hashtable = new Hashtable<>(); hashtable.put("a", "80%"); System.out.println(hashtable.get("a")); Collections.synchronizedXXX()  虽然这两个类不是线程安全的,但是可以用 Collections.synchronizedList(new ArrayList<Integer>())、Conllections.synchroniz....