Day17 集合与并发编程

本文深入探讨了Java集合框架中的HashMap,包括其数据结构、哈希算法以及并发处理。HashMap基于Entry数组存储数据,通过位移操作确定存储空间。在并发环境下,文章介绍了线程安全问题及解决方案,如线程安全类和同步锁机制,并讨论了线程池在高并发场景下的重要性。
摘要由CSDN通过智能技术生成

集合规约

集合是数据结构的载体

Java集合类图,参考Java源码

请添加图片描述

红色:接口
蓝色:抽象类
绿色:并发包中的类
灰色:早期线程安全的类


数据结构与时间复杂度

数据结构:指逻辑意义上的 数据组织方式 及其 对应的处理方式

数据组织方式

线性结构、树结构、图结构、哈希结构

数据处理方式

增删改查:以某种特定的算法实现数据的增加、删除、查找、遍历

从最好的到最坏的时间复杂度如下

常数级O(1),对数级O(logN),线性级(N),线性对数级O(NlogN),平方级O(N^2),指数级O(2N), 阶乘级(N!)


HashMap的基本概念

哈希类集合的三个基本存储概念

名称说明
table存储所有节点数据的数组
slot哈希槽。即table[i]这个位置
bucket哈希桶。table[i]上的所有元素形成的表或树的集合

HashMap的主干是一个Entry数组

Entry是HashMap的基本组成单元,每一个Entry包含Node内部类


HashMap的哈希算法

如何为初始容量为13的HashMap分配存储空间?

应该分配16个空间(比13大的最小二的整数幂)

利用 -1(补码1111 1111 1111 1111 1111 1111 1111 1111)位移获取最接近13的1111...,进而获取二的整数幂
解决的问题:
左边的1应该往右边移动多少位?
  • numberOfLeadingZeros就是计算移动多少位的方法
  • 入参13-1=12,执行红色框代码 if(i >= 1 << 2){n -= 2; i >>>= 2;}
  • (12 >= 4)为true,n = 29,i = 11(二进制)
  • n - (i >>> 1) = 28
  • -1 往右边移动28位,得到1111(15)
  • 经由tableSizeFor()判断,返回 n + 1 = 16
  • 分配的内存空间为16
static final int tableSizeFor(int cap) {
	int n = -1 >>> Integer.numberOfLeadingZeros(cap - 1);
	return (n < 0)? 1 : (n > MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}

// 跟上面的一样
static final int tableSizeFor(int cap) {
	int n = -1 >>> Integer.numberOfLeadingZeros(cap - 1);
    if(n < 0) {
        return 1;
    } else if(n > MAXIMUM_CAPACITY) {
        return MAXIMUM_CAPACITY;
    } else {
        return n + 1;
    }
}

public static int numberOfLeadingZeros(int i) {
	if(i <= 0) {
		return i == 0 ? 32 : 0;
	}
	int n = 31;
	if(i >= 1 << 16){n -= 16; i >>>= 16;} // 65536
	if(i >= 1 << 8){n -= 8; i >>>= 8;} // 256
	if(i >= 1 << 4){n -= 4; i >>>= 4;} // 16
	if(i >= 1 << 2){n -= 2; i >>>= 2;} // 4
    return n - (i >>> 1);
}
>>>无符号右移
>>有符号右移

位移的好处就是快,不需要两个运算器,在晶体管内移动,无需加法器(会很慢)

写 1 << 2 而不是直接写 4 的原因,在计算机内还需要对4进行转换,不如直接位移

if(i >= 1 << 2){n -= 2; i >>>= 2;}的目的:得到挪动的位数
现在是用1101(13) 找 1111
具体做法就是用 -1 (1111 1111 1111 1111 1111 1111 1111 1111)来挪,看挪动的位数
(算法就是上面的算法,Java已经给好了)
最后找到1111后,经过判断后即可返回待分配的空间

并发处理

什么是并行与并发

并行是指同时处理多任务的能力

并发是指在某一时间段内,多任务交替处理的能力


同一CPU不同时刻交替执行不同的方法,是并发

不同CPU同一时刻执行不同的方法,是并行


延伸到计算机线程处理过程,各个线程轮流占用CPU的计算资源,可能会出现某个线程尚未执行完就不得不中断的情况,容易导致线程不安全

线程安全问题只在多线程环境下才出现,单线程串行执行不存在此问题

保证高并发场景下的线程安全,可以从以下四个维度考量

  • 数据单线程内可见
  • 只读对象
  • 线程安全类
  • 同步锁机制

AQS锁

Abstract 抽象:包含5个抽象方法,具体由子类实现

Queued 队列:利用队列来管理竞争共享资源的多线程

Synchronizer 同步器:是解决多线程同步问题的工具

AQS的使用场景

1、线程同步类
2、线程池
3、线程安全Queue/List/Map


线程与线程池

线程池的作用

1、管理并复用线程、控制最大并发数等

2、增加对线程的管理,快速排查问题

3、实现任务线程队列缓存策略和拒绝机制

4、实现某些与时间相关的功能,如定时执行、周期执行等

5、隔离线程环境


线程池的用处

1、消息框架实现消费的线程管理

2、数据库实现SQL语句执行的线程管理

3、RPC框架内实现长链接的线程管理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值