0%

声明: 本文基于 JDK1.8

引子

线程池的作用

  1. 减少资源开销

    线程可以重用,减少每次创建线程、销毁线程的开销。

  2. 提高响应速度

    每次请求到来,由于线程已经创建好,故可以直接执行任务。

  3. 提高线程的可管理性

    线程过多会占用大量资源,导致 OOM 等问题,同时会造成相互之间竞争。线程池可以对线程的创建与停止、线程的数量等加以控制,提高系统稳定性。

  4. 提供定期、延时等功能

阅读全文 »

问题描述

我们知道,当 HashMap 中的元素达到一定值(这个值称作 threshold)后,会进行扩容,扩容后,数组的长度会变成原始数组的两倍,需要把原始数组中的元素重新散列到新数组中(这个过程称作 rehash)。

例如,原始 Node 数组的长度为 16 时,哈希值为 2, 18, 34, 50, 66 的元素都会被放在数组下标为 2 的位置。扩容后,新 Node 数组的长度变为 32,这些元素将会被分别放到不同的位置:

阅读全文 »

问题描述

最近翻看 JDK8 源码,发现 Integer 的两个有意思的方法:numberOfLeadingZeros 和 numberOfTrailingZeros。

这两个方法作用很好理解,就是返回一个二进制整数最左边或最右边连续的0的个数。

普通人的解法

粗略地想了下,我应该会这么实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static int getIntegerLeadingZeros(int i) {
if (i < 0)
return 0;
if (i == 0)
return 32;
int c = 0;
while (i > 0) {
i >>>= 1;
c++;
}
return 32 - c;
}

public static int getIntegerTrailingZeros(int i) {
if (i == 0)
return 32;
int c = 0;
while (i != 0) {
i <<= 1;
c++;
}
return 32 - c;
}
阅读全文 »

ConcurrentHashMap 锁粒度

JDK8 中,ConcurrentHashMap 的锁粒度变小,不再是对 Segment 加锁,而是对桶的头结点加锁,这样大大提高的并发的性能。

那么在没有锁的情况下,如何保证多个线程的 put 不会相互覆盖?

无锁实现:for 循环 + CAS

CAS,即 compareAndSwap,原子的执行比较并交换的操作:当前内存值如果和预期值相等,则将其更新为目标值,否则不更新。

阅读全文 »

问题定义

生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多进程/多线程同步问题的经典案例。

生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。

阅读全文 »

方法定义

在 Java 中,在线程中调用 wait() 方法,将阻塞等待其他线程的通知(其他线程调用 notify() 方法或 notifyAll() 方法),在线程中调用 notify() 方法或 notifyAll() 方法,将通知其他线程从 wait() 方法处返回。

Object 是所有类的超类,它有 5 个方法组成了等待/通知机制的核心:notify()、notifyAll()、wait()、wait(long)和 wait(long,int)。

阅读全文 »

源码解释

在 Java 的 HashMap 源码中,put() 和 get() 方法会首先获取 key 的哈希值。

1
2
3
4
5
6
7
8
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}

public V get(Object key) {
Node<K,V> e;
return (e = getNode(hash(key), key)) == null ? null : e.value;
}
阅读全文 »

问题描述

有 n 位乘客即将登机,飞机正好有 n 个座位。第一位乘客的票丢了,他随便选了一个座位坐下。

剩下的乘客将会:

  • 如果他们自己的座位还空着,就坐到自己的座位上,

  • 当他们自己的座位被占用时,随机选择其他座位
    第 n 位乘客坐在自己的座位上的概率是多少?

来源:https://leetcode-cn.com/problems/airplane-seat-assignment-probability

阅读全文 »

问题定义

有一个背包,他的容量为 C (Capacity)。现在有n中不同的物品,编号为 0…n-1,其中每一件物品的重量为 w(i),价值为 v(i)。问可以向这个背包中盛放哪些物品,使得在不超过背包容量的基础上,物品的总价值最大。

解决方法

状态定义

对于这类组合问题,需要用两个变量来定义状态。

用 f(n, c) 表示将 n 个物品放进容量为 c 的背包可以获得的最大值。

阅读全文 »

什么是泛型

Java泛型设计原则:只要在编译时期没有出现警告,那么运行时期就不会出现ClassCastException异常

泛型:把类型明确的工作推迟到创建对象或调用方法的时候才去明确的特殊的类型

参数化类型:
- 把类型当作参数一样传递
- <数据类型> 只能是应用类型

阅读全文 »