探秘 JVM:运行时数据区

JVM 内存区域从概念模型上主要分为 堆、元空间、java 虚拟机栈、本地方法栈、程序计数器 五大模块,其中前两者属于线程共享,而后三者属于线程私有,如下图(以 HotSpot 虚拟机为例):

image

说明:元空间在 java 8 中引入,替换之前的方法区。

阅读全文

Java 语言实现单例模式的若干种方式

在面向对象程序设计中,只要内存允许我们通常都可以为一个对象创建任意多个实例,但是一些场景下这不一定是一件好的事情。考虑一个文件类,在被使用之前需要从磁盘加载一定量的数据,我们肯定不希望每次调用该对象都去执行数据加载的操作,不仅费时,而且同样的数据因为一个对象的实例化操作就要在内存中重复存储一份,显然是对内存的一种浪费。这个时候我们就希望对数据的加载操作只执行一次,后面所有的调用都是对这份数据的复用,而这也正式单例模式的应用场景。

如果可以任意的创建对象,那么当我们希望内存中仅保有一份实例,就必须让所有的程序开发人员维持一个约定,只实例化该对象一次,然而现实是对象是可以任意被实例化的,约定开发人员是不现实的。这个时候我们就需要从开发人员手中剥夺对目标对象实例化的权利,而由单例模式去控制对象的创建,并暴露给开发人员一个获取对象实例的入口。

阅读全文

Java 8th 函数式编程:默认接口方法

Java 8th 可以看做是 java 版本更新迭代过程中变化最大的几个版本之一(与时俱进,方能不灭),但是经过这么多年的发展和迭代,java 的源码俨然已是一个庞然大物,要在这样庞大的体积上大动干戈必定不易。所以当第一次看到默认接口方法的时候,我第一感觉就是这是设计人员在填自己之前挖的坑。

从前几篇的讲解中我们知道 8th 在现有的接口上添加了许多方法,比如 List 的 sort(Comparator<? super E> c) 方法。如果按照 8th 之前接口的设计思路,当给一个接口添加方法声明的时候,实现该接口的类都必须为该新添加的方法添加相应的实现(或将自己设置为抽象类)。考虑兼容性这样是不可取的,所以说这是一个坑,而新的特性又要求不得不为接口添加一些新的方法,为了兼得鱼和熊掌,设计人员提出了默认接口方法的概念。

阅读全文

Java 8th 函数式编程:流式数据处理

第一次接触到流式数据处理的时候,第一感觉是流式数据处理让集合操作变得简洁了许多,通常我们需要多行代码才能完成的操作,借助于流式数据处理可以在一行中实现。比如我们希望对一个包含整数的集合筛选出所有的偶数,并将其封装成为一个新的集合返回,那么在 8th 之前,我们需要通过如下代码实现:

1
2
3
4
5
6
List<Integer> evens = new ArrayList<>();
for (final Integer num : nums) {
if (num % 2 == 0) {
evens.add(num);
}
}
阅读全文

Java 8th 函数式编程:Optional 类型

NullPointException 可以说是所有 java 程序员都遇到过的一个异常,虽然 java 从设计之初就力图让程序员脱离指针的苦海,但是指针确实是实际存在的,而 java 设计者也只能是让指针在 java 语言中变得更加简单、易用,而不能完全的将其剔除,所以才有了我们日常所见到的关键字 null

空指针异常是一个运行时异常,对于这一类异常,如果没有明确的处理策略,那么最佳实践在于让程序早点挂掉,但是很多场景下不是开发人员没有具体的处理策略,而是根本没有意识到空指针异常的存在。当异常真的发生的时候,处理策略也很简单,在存在异常的地方添加一个 if 语句判定即可,但是这样的应对策略会让我们的程序出现越来越多的 null 判定。

阅读全文

Java 8th 函数式编程:lambda 表达式

Lambda 表达式是 java 8th 给我们带来的几个重量级新特性之一,借用 lambda 表达式可以让我们的程序设计更加简洁。最近新的项目摒弃了 6th 版本,全面基于 8th 进行开发,本文将探讨 行为参数化lambda 表达式 ,以及 方法引用 等知识点。

一. 行为参数化

行为参数化简单的说就是将方法的逻辑以参数的形式传递到方法中,方法主体仅包含模板类通用代码,而一些会随着业务场景而变化的逻辑则以参数的形式传递到方法之中,采用行为参数化可以让程序更加的通用,以应对频繁变更的需求。

阅读全文

转载:细聊分布式 ID 的生成方法

需求缘起

几乎所有的业务系统,都有生成一个记录标识的需求,例如:

  1. 消息标识:message-id
  2. 订单标识:order-id
  3. 帖子标识:tiezi-id

这个记录标识往往就是数据库中的唯一主键,数据库上会建立聚集索引(cluster index),即在物理存储上以这个字段排序。

阅读全文

CAP 理论与分阶段提交协议

在分布式系统中著有 CAP 理论,该理论由加州大学伯克利分校的 Eric Brewer 教授提出,阐述了在一个分布式系统中不可能同时满足一致性( C onsistency)、可用性( A vailability),以及分区容错性( P artition Tolerance)。

  • 一致性 :在分布式系统中数据往往存在多个副本,一致性描述的是这些副本中的数据在内容和组织上的一致。
  • 可用性 :描述系统对用户的服务能力,所谓可用是指在用户能够容忍的时间范围内返回用户期望的结果。
  • 分区容错性 :分布式系统通常由多个节点构成,由于网络是不可靠的,所以存在分布式集群中的节点因为网络通信故障导致被孤立成一个个小集群的可能性,即网络分区,分区容错性要求在出现网络分区时系统仍然能够对外提供一致性的可用服务。
阅读全文

基于锁分段机制的 ConcurrentHashMap 实现内幕

ConcurrentHashMap 是线程安全的 HashMap。此前,HashTable 一直被认为是线程安全的 HashMap,ConcurrentHashMap 相对于 HashTable 采用了 锁分段机制 ,即将原本对整个对象加锁的实现进行粒度细化。这也是源于 HashMap 基本的存储特性,因为许多读写请求都是被哈希到了互相独立的区域,这种情况下即使并发读写也不会相互影响,更不会有线程安全问题,而对于操作加全局锁的实现方式显然是浪费了这一天然的并发优势,我们需要加锁的位置是真正存在竞争的地方,而分段锁很好的利用了这一特点。

阅读全文

Java 异常处理机制与最佳实践

这周小组内的学习是探讨 java 异常处理的最佳实践,今天周末,外面太闷,宅在家里对 java 的异常处理的个人立即做一个总结,如有不对的地方欢迎指正~

一. 谈谈个人对 java 异常处理的看法

维基百科对于异常处理的定义是:

异常处理,是编程语言或计算机硬件里的一种机制,用于处理软件或信息系统中出现的异常状况(即超出程序正常执行流程的某些特殊条件)。

阅读全文