《极客时间教程 - Java 并发编程实战》笔记三
Immutability 模式:如何利用不变性解决并发问题?
解决并发问题,其实最简单的办法就是让共享变量只有读操作,而没有写操作。这个办法如此重要,以至于被上升到了一种解决并发问题的设计模式:不变性(Immutability)模式。所谓不变性,简单来讲,就是对象一旦被创建之后,状态就不再发生变化。换句话说,就是变量一旦被赋值,就不允许修改了(没有写操作);没有修改操作,也就是保持了不变性。
大道至简,知易行难
解决并发问题,其实最简单的办法就是让共享变量只有读操作,而没有写操作。这个办法如此重要,以至于被上升到了一种解决并发问题的设计模式:不变性(Immutability)模式。所谓不变性,简单来讲,就是对象一旦被创建之后,状态就不再发生变化。换句话说,就是变量一旦被赋值,就不允许修改了(没有写操作);没有修改操作,也就是保持了不变性。
Guava 是 Google 开源的 Java 类库,提供了一个工具类 RateLimiter。
【示例】使用 RateLimiter 限流
//限流器流速:2 个请求/秒
RateLimiter limiter = RateLimiter.create(2.0);
//执行任务的线程池
ExecutorService es = Executors.newFixedThreadPool(1);
//记录上一次执行时间
prev = System.nanoTime();
//测试执行 20 次
for (int i = 0; i < 20; i++) {
//限流器限流
limiter.acquire();
//提交任务异步执行
es.execute(() -> {
long cur = System.nanoTime();
//打印时间间隔:毫秒
System.out.println((cur - prev) / 1000_000);
prev = cur;
});
}
// 输出结果:
// ...
// 500
// 499
// 500
// 499
并发编程可以总结为三个核心问题:分工、同步、互斥。
已有 synchronized,还支持 Lock 的原因是,需要一把锁支持:
从虚拟机视角来看,执行 Java 代码首先需要将它编译而成的 class 文件加载到 Java 虚拟机中。加载后的 Java 类会被存放于方法区(Method Area)中。实际运行时,虚拟机会执行方法区内的代码。
略
JVM - Java Virtual Machine 的缩写,即 Java 虚拟机。JVM 是运行 Java 字节码的虚拟机。JVM 不理解 Java 源代码,这就是为什么要将 *.java
文件编译为 JVM 可理解的 *.class
文件(字节码)。Java 有一句著名的口号:“Write Once, Run Anywhere(一次编写,随处运行)”,JVM 正是其核心所在。实际上,JVM 针对不同的系统(Windows、Linux、MacOS)有不同的实现,目的在于用相同的字节码执行同样的结果。
通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。如果想实现每一个线程都有自己的专属本地变量该如何解决呢?
JDK 中自带的ThreadLocal
类正是为了解决这样的问题。 ThreadLocal
类主要解决的就是让每个线程绑定自己的值,可以将ThreadLocal
类形象的比喻成存放数据的盒子,盒子中可以存储每个线程的私有数据。
JMM(Java 内存模型)相关的问题比较多,也比较重要,于是我单独抽了一篇文章来总结 JMM 相关的知识点和问题:JMM(Java 内存模型)详解 。
Java 泛型(Generics) 是 JDK 5 中引入的一个新特性。使用泛型参数,可以增强代码的可读性以及稳定性。
编译器可以对泛型参数进行检测,并且通过泛型参数可以指定传入的对象类型。比如 ArrayList<Person> persons = new ArrayList<Person>()
这行代码就指明了该 ArrayList
对象只能传入 Person
对象,如果传入其他类型的对象就会报错。
典型问题
面向对象编程和面向过程编程有什么区别?
知识点
二者的主要区别在于解决问题的方式不同:
另外,面向对象开发的程序一般更易维护、易复用、易扩展。
💧 dunwu.github.ioopen in new window 是个人的技术文档归档仓库。
- 🔁 项目同步维护:Githubopen in new window
- 📖 电子书阅读:Github Pagesopen in new window
Pattern
、Matcher
、捕获与非捕获
、反向引用
、零宽断言
、贪婪与懒惰
、元字符
、DFA
、NFA
Base64
、消息摘要
、数字签名
、对称加密
、非对称加密
、MD5
、SHA
、HMAC
、AES
、DES
、DESede
、RSA
Locale
、ResourceBundle
、NumberFormat
、DateFormat
、MessageFormat
Stream
、lambda
、Optional
、@FunctionalInterface
SPI
、ClassLoader
Collection
、泛型
、Iterable
、Iterator
、Comparable
、Comparator
、Cloneable
、fail-fast
List
、ArrayList
、LinkedList
Map
、HashMap
、TreeMap
、LinkedHashMap
、WeakHashMap
Set
、HashSet
、TreeSet
、LinkedHashSet
、EmumSet
Queue
、Deque
、ArrayDeque
、LinkedList
、PriorityQueue
InputStream
、OutputStream
、Reader
、Writer
、阻塞
Channel
、Buffer
、Selector
、非阻塞
、多路复用
Serializable
、serialVersionUID
、transient
、Externalizable
、writeObject
、readObject
Socket
、ServerSocket
、DatagramPacket
、DatagramSocket
File
、RandomAccessFile
、System
、Scanner
并发
、线程
、安全性
、活跃性
、性能
、死锁
、活锁
JMM
、Happens-Before
、内存屏障
、volatile
、synchronized
、final
、指令重排序
Thread
、Runnable
、Callable
、Future
、wait
、notify
、notifyAll
、join
、sleep
、yeild
、线程状态
、线程通信
CAS
、自旋锁
ThreadLocal
AQS
AQS
、ReentrantLock
、ReentrantReadWriteLock
、Condition
CAS
、Atomic
ConcurrentHashMap
、CopyOnWriteArrayList
Executor
、ExecutorService
、ThreadPoolExecutor
、Executors
CountDownLatch
、CyclicBarrier
、Semaphore
程序计数器
、虚拟机栈
、本地方法栈
、堆
、方法区
、运行时常量池
、直接内存
、OutOfMemoryError
、StackOverflowError
GC Roots
、Serial
、Parallel
、CMS
、G1
、Minor GC
、Full GC
bytecode
、asm
、javassist
ClassLoader
、双亲委派
jps
、jstat
、jmap
、jstack
、jhat
、jinfo
、jconsole
、jvisualvm
、MAT
、JProfile
、Arthas
CPU
、内存
、磁盘
、网络
、GC
配置
、调优
Tomcat 和 Jetty 都是 Java 比较流行的轻量级服务器。
Nginx 是目前最流行的反向代理服务器,也常用于负载均衡。
Java 项目需要通过 构建工具 来管理项目依赖,完成编译、打包、发布、生成 JavaDoc 等任务。
- 目前最主流的构建工具是 Maven,它的功能非常强大。
- Gradle 号称是要替代 Maven 等构件工具,它的版本管理确实简洁,但是需要学习 Groovy,学习成本比 Maven 高。
- Ant 功能比 Maven 和 Gradle 要弱,现代 Java 项目基本不用了,但也有一些传统的 Java 项目还在使用。
自从有了 IDE,写代码从此就告别了刀耕火种的蛮荒时代。
- Eclipse 是久负盛名的开源 Java IDE,我的学生时代一直使用它写 Java。
- 曾经抗拒从转 Intellij Idea ,但后来发现真香,不得不说,确实是目前最优秀的 Java IDE。
- 你可以在 vscode 中写各种语言,只要安装相应插件即可。如果你的项目中使用了很多种编程语言,又懒得在多个 IDE 之间切换,那么就用 vscode 来一网打尽吧。
监控/诊断 工具主要用于 Java 应用的运维。通过采集、分析、存储、可视化应用的有效数据,帮助开发者、使用者快速定位问题,找到性能瓶颈。
Java 领域比较流行的安全框架就是 shiro 和 spring-security。
shiro 更为简单、轻便,容易理解,能满足大多数基本安全场景下的需要。
spring-security 功能更丰富,也比 shiro 更复杂。值得一提的是由于 spring-security 是 spring 团队开发,所以集成 spring 和 spring-boot 框架更容易。
缓存可以说是优化系统性能的第一手段,在各种技术中都会有缓存的应用。
如果想深入学习缓存,建议先了解一下 缓存基本原理open in new window,有助于理解缓存的特性、原理,使用缓存常见的问题及解决方案。
关系型数据库 整理主流关系型数据库知识点。
Mysql 架构、Mysql 存储引擎、Mysql 索引、Mysql 事务、Mysql 锁、Mysql 高可用、Mysql 优化、Mysql 运维、Mysql 面试
MongoDB 是一个基于文档的分布式数据库,由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
MongoDB 是一个介于关系型数据库和非关系型数据库之间的产品。它是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 json 的 bson 格式,因此可以存储比较复杂的数据类型。
MongoDB 最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
Redis 基本数据类型、Redis 高级数据类型、Redis 数据结构、Redis 过期删除和内存淘汰、Redis 持久化、Redis 事件、Redis 复制、Redis 哨兵、Redis 集群、Redis 发布订阅、Redis 独立功能、Redis 管道、Redis 脚本、Redis 运维、Redis 实战、Redis 面试
Elasticsearch 是一个基于 Lucene 的搜索和数据分析工具,它提供了一个分布式服务。Elasticsearch 是遵从 Apache 开源条款的一款开源产品,是当前主流的企业级搜索引擎。
如果你是做通信领域的开发,或者是 Web 应用的开发,那就或多或少需要了解一些计算机网络的知识 。
理解计算机网络,首先需要从宏观层面了解计算机网络通信的分层结构。最有代表性的是 OSI 七层结构模型,但现实中更流行的是五层结构模型。
了解网络分层结构,需要了解每个网络层级在网络通信中的定位,以及这个层级主要的通信设备、通信协议。
PPP
、CSMA/CD
、局域网、以太网、MAC
、适配器、集线器、网桥、交换机IP
、ICMP
、ARP
、路由UDP
、TCP
、滑动窗口、拥塞控制、三次握手HTTP
、DNS
、FTP
、TELNET
、DHCP
指标
、挑战
、超时检测
、NTP
、逻辑时钟
逻辑时钟
、向量时钟
、版本时钟
、全序
、偏序
ACID
、CAP
、BASE
、一致性
共识
共识
、Paxos
共识
、Raft
Gossip
共识
、ZAB
、ZooKeeper
服务注册
、服务发现
、元数据
轮询
、随机
、最少连接
、源地址哈希
、一致性哈希
、虚拟 hash 槽
限流
、熔断
、降级
、计数器法
、时间窗口法
、令牌桶法
、漏桶法
路由
、条件路由
、脚本路由
、标签路由
UUID
、自增序列
、雪花算法
、Leaf
定义
、演进
、利弊
、如何拆分
、容量规划
、核心组件
服务定义
、注册中心
、元数据
、健康检查
、服务订阅
、一致性
RPC
、通信协议
、传输方式
、序列化
微服务
、序列化
、动态代理
、通信
、服务注册发现
、健康检查
、路由
、负载均衡
、容错处理
、优雅上线下线
、限流
、熔断
、业务分组
创建型模式提供了创建对象的机制, 能够提升已有代码的灵活性和可复用性。
结构型模式介绍如何将对象和类组装成较大的结构, 并同时保持结构的灵活和高效。
行为模式负责对象间的高效沟通和职责委派。