面试之Java基础 - 实践

hashCode与equals方法重写

public class Test1 {
private Long x;
private String y;
private Integer w;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Test1 test1 = (Test1) o;
return Objects.equals(x, test1.x) && Objects.equals(y, test1.y) && Objects.equals(w, test1.w);
}
@Override
public int hashCode() {
return Objects.hash(x, y, w);
}
}

== 与equal

== 对比的是栈中的值, 基本数据类型是 变量的值, 引用类型是 对象内存地址。

和==一样, 不过一般都会重写equal方法。就是equals:默认

ConcurrentHashMap

HashMap:https://blog.csdn.net/qinwenjng120/article/details/150960136

ConcurrentHashMap:

https://blog.csdn.net/qinwenjng120/article/details/150933009

描述

1.7版本

1. 数据结构:ReetrantLock + Segment +HashEntry

2. get:两次hash, 第一次定位setment, 第二次定位到元素所在的链表的头部,然后通过equal比较。 查询无需加锁,通过volatile保证可见性。

3. put :   Segment分段锁,继承ReetrantLock, 锁的粒度是Segment, 其他Segment不受影响。

4. 扩容时,只扩容当前segment内的数组

1.8版本

1. 数据结构:synchronized + CAS + Node + 红黑树

2. get:无锁,Node的val和next都用volatile修饰,保证可见性; 数组用volatile修饰,保证扩容时被读线程感知。

3. put:锁链表的head节点,不影响其他元素的读写,锁的粒度更细;

4. 扩容时,阻塞所有的读写操作,并发扩容。

扩容机制

1.7版本

  • ConcurrentHashMap基于Segment分段锁实现
  • 每个Segment内部是个小型的HashMap
  • 每个Segment扩容,随后转移元素到新的数组中,扩容时数组变成原来的两倍
  • 扩容判断的是每个Segment内部独立判断的,判端是否超过阈值。

1.8版本

  • 不再基于Segment分段锁实现
  • 当某个线程put时,发现ConcurrentHashMap在扩容,则一起进行扩容(支持多线程同时扩容)
  • 当某个线程put时,发现ConcurrentHashMap不是在扩容,就将元素放入,随后判断是否超过阈值,超过则进行扩容
  • 扩容时,先 生成一个新的数据;先将原数组分组,将每组分给不同的线程来进行元素转移,每个线程负责一组或多组元素的转移。

posted @ 2025-09-17 18:58  yjbjingcha  阅读(7)  评论(0)    收藏  举报