1 等待多线程完成的 CountDownLatch

例如:解析一个 Excel 里多个 sheet 的数据,如果使用多线程,每个线程解析一个 sheet 里的数据,等到所有的 sheet 都解析完之后,程序提示解析完成。

即,需要主线程等待所有线程完成 sheet 的解析操作,最简单的做法是使用 join() 方法,代码8-1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class JoinCountDownLatchTest {
public static void main(String[] args) throws Exception {
Thread parser1 = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("parser1 finish");
}
});
Thread parser2 = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("parser2 finish");
}
});
parser1.start();
parser2.start();
parser1.join();
parser2.join();
System.out.println("all parser finish");
}
}

阅读全文 »

1 ConcurrentHashMap 的实现原理与使用

1.1 为什么要使用 ConcurrentHashMap

  1. 线程不安全的 HashMap ,在多线程下 HashMap 的 Entry 链表导致形成环形数据结构, Entry 的 next 节点永远不为空,就会产生死循环获取 Entry 。
  2. 效率低下的 HashTable ,使用 synchronized 保证线程安全。
  3. ConcurrentHashMap 的锁分段技术有效提升并发访问率。 HashTable 效率低下是因为所有访问 HashTable 的线程都必须竞争同一把锁,如果容器里
    有多把锁,每把锁用于锁容器其中一部分数据,那么当多线程访问容器里不同数据段的数据时,线程就不会存在锁竞争。
阅读全文 »

1 线程简介

1.1 什么是线程

操作系统运行一个程序时,会为其创建一个进程。而操作系统调度的最小单元是线程,也叫轻量级进程( Light Weight Process),
在一个进程里可以创建多个线程,这些线程都拥有各自的计数器、堆栈和局部变量等属性,并且能够访问共享的内存变量。
处理器在这些线程上高速切换,让使用者感觉到这些线程在同时执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class MultiThread{
public static void main(String[] args) {
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);
for(ThreadInfo threadInfo : threadInfos) {
System.out.println(threadInfo.getThreadId() + "," + threadInfo.getThreadName());
}
/**
6,Monitor Ctrl-Break
5,Attach Listener
4,Signal Dispatcher
3,Finalizer
2,Reference Handler
1,main
*/
}
}

阅读全文 »

1 数据发布/订阅

数据发布/订阅(Pulish/Subscribe)系统,即所谓的配置中心,顾名思义就是发布者将数据发布到ZooKeeper的一个或一系列节点上,供订阅者进行数据订阅, 进而达到动态获取数据的目的,实现配置信息的集中式管理和数据的动态更新。

发布/订阅系统一般有两种设计模式,分别是推(Push)模式和拉(Pull)模式。在推模式中,服务端主动将数据更新发送给所有订阅的客户端;而拉模式则是由 客户端主动发起请求获取最新数据,通常客户端都采用定时进行轮询拉取的方式。ZooKeeper采用的是推拉结合的方式:客户端向服务端注册自己需要关注的 节点,一旦该节点的数据发生变更,那么服务端就会向相应的客户端发送Watcher事件通知,客户端接收到这个消息通知之后,需要主动到服务端获取最新的数据。

阅读全文 »

本章概要:
首先对ZooKeeper进行一个整体上的介绍,包括ZooKeeper的设计目标、由来以及它的基本概念,然后将会重点介绍ZAB这一ZooKeeper中非常重要的一致性协议。

1. 初识ZooKeeper

1.1 ZooKeeper介绍

ZooKeeper由雅虎创建,是Chubby的开源实现。设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。

阅读全文 »

前章提要:
主要从理论上讲解了Paxos算法,如何在保证数据一致性的情况下兼顾稳定性和性能也是一个巨大的挑战。从本章开始,我们将结合实际工程实际中的Paxos实现, 来讲解如何真正地使用Paxos算法来解决分布式一致性问题。

1. Chubby

Google Chubby是一个大名鼎鼎的分布式锁服务,GFS和Big Table等大型系统多用它来解决分布式协作、元数据存储和Master选举等一系列与分布式锁服务相关的问题。 Chubby的底层一致性实现就是以Paxos算法为基础的,这给Paxos算法的学习者提供了一个理论联系的范例,从而可以了解到Paxos算法是如何在实际工程中得到应用的。

阅读全文 »

前章提要:
上章我们讲到分布式往往会在系统可用性和数据一致性之间反复权衡,于是就产生了一系列的一致性协议(为什么没有可用性协议?博主认为,数据才是王道)。

1. 2PC和3PC

在分布式系统总,每一个机器节点虽然都能够明确地知道自己在进行事务操作过程中的结果是成功或失败,但却无法直接获取到其他分布式节点的操作结果。 因此,当一个事务操作需要跨越多个分布式节点的时候,为了保持事务处理的ACID特性(某个节点为单位),就需要引入一个称为“协调者(Coordinator)” 的组件来统一调度所有分布式节点的执行逻辑,这些被调度的分布式节点被称为“参与者(Participant)”。

阅读全文 »

1. 从集中式到分布式

1.1 集中式的特点

所谓的集中式系统就是指由一台或多台主计算机组成中心节点,数据集中存储于这个中心节点,并且整个系统的所有业务单元都部署在这个中心节点上, 系统的所有功能均由其集中处理。也就是说,在集中式系统中,每个终端或客户端机器仅仅负责数据的录入和输出,而数据的存储与控制处理完全 交由主机来完成。

阅读全文 »