目录

Life in Flow

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

存档: 2020 年 03 月 (19)

Netty 背景与领域知识

Netty 背景  Netty 由 Trustin Lee (韩国、Line 公司) 2004 年开发。 * 本质:网络应用程序框架 * 实现:异步、事件驱动 * 特性:高性能、可维护、快速开发 * 用于:开发服务器和客户端 为什么不直接使用 JDK NIO  直接使用 JDK NIO = 一个人在战斗。 Netty 做的更多 * 支持常用应用层协议。 * 解决传输问题:粘包、半包现象。 * 支持流量整形。 * 完善的断连、Idle 等异常处理等。 Netty 做的更好 * 规避 JDK NIO bug: epoll bug (异常唤醒空转导致 CPU 100%) JDK NIO 2.4 版本。 * API 更优化、更强大。 * 隔离变化、屏蔽细节。 * 直接用 JDK 实现,代码量太多、BUG 也多。 * Netty 已经维护了 15 年。 网络通信框架对比  Netty 没有竞争对手。 * Apache Mina (Trustin Lee 背书 Netty) * Sun Grizzly (用的少、文档少、更新少) * Apple Swift NIO、ACE 等 (其他语言、....

High Performance Cache

缓存作用  缓存是在实际生产中非常常用的工具,用了缓存以后,我们可以避免重复计算,提高吞吐量。  一个功能完备、性能强劲的缓存,需要考虑的点非常多。 第一阶段 如果不使用 synchronized 多线程同时 put、扩容时候会出现线程安全隐患 使用 synchronized 性能差,多线程需要串行化的方式执行 doCompute 代码复用性差,代码侵入性强,违反开闭原则。 * 性能差:多个线程同时想计算的时候,需要慢慢等待(同步方法) import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; /** * 描述: 最简单的缓存形式:HashMap */ public class ImoocCache1 { //final 增加安全性,可读性 private final HashMap<String,Integer> cache = new HashMap<>(); public synchronized Integer computer(Str....

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....