面试中经常问到的线程安全的集合类,这样回答会显得很优雅

前言:
本篇文章主要讲解面试中经常问到的线程安全的集合类的知识。该专栏比较适合刚入坑Java的小白以及准备秋招的大佬阅读。

如果文章有什么需要改进的地方欢迎大佬提出,对大佬有帮助希望可以支持下哦~

小威在此先感谢各位小伙伴儿了😁

在这里插入图片描述

以下正文开始


在这里插入图片描述

线程安全的类,集合,关键字总结

Java中的部分类,集合,关键字都能保证线程安全,接下来我们从线程安全的类,集合,关键字详细介绍:

线程安全类

线程安全类:线程安全类是一些经过设计,能够在多线程环境下安全地使用的类,它们大多数都是通过内部实现同步机制保证正常工作。线程安全类主要有以下几种:

  • StringBuffer:线程安全的字符串缓冲区,所有对于它的操作都是同步的。
  • Vector:线程安全的数组序列,支持对其中的元素进行增删查改等操作。
  • Hashtable:线程安全的哈希表,也就是键值对映射(Map),所有对于它的操作都是同步的。
  • ConcurrentHashMap:线程安全的哈希表,采用了分段锁的方式,不同线程可以同时对不同的分段进行操作。

线程安全集合

线程安全集合:线程安全集合是能够在线程安全的前提下支持快速地添加、查询、删除其中元素的集合。Java中线程安全的集合主要有以下几种:

  • CopyOnWriteArrayList:线程安全的动态数组,它对于写操作会复制当前数组,修改完后再将它赋值给原引用,因此读操作和写操作可以同时进行而不需要加锁。
  • CopyOnWriteArraySet:线程安全的集合,它采用了CopyOnWriteArrayList来实现,保证了元素唯一、有序,并且在读操作的同时也可以进行写操作
  • ConcurrentLinkedQueue:线程安全的队列,它采用了CAS(Compare And Swap)算法来保证并发操作时的原子性。

线程安全方法

线程安全方法:Java中也提供了许多线程安全方法,这些方法在多线程环境下能够保证数据的正确性,主要有以下几种:

  • synchronized关键字:能够锁住当前代码块或方法,保证同一时间只能有一个线程进入执行该代码块或方法。
  • volatile关键字:保证变量的可见性以及禁止指令重排序,从而保证多线程情况下变量的正确性。
  • Atomic类:提供了一组原子操作方法,使用CAS算法保证操作的原子性。
  • Lock接口及其实现类:提供了更加灵活的锁机制,支持不可重入锁、可重入锁以及读写锁等。
  • ThreadLocal类:为每个线程提供了独立的变量副本,从而避免了线程安全问题。

StringBuffer

StringBuffer是Java中用于字符串操作的可变类,它在多线程环境下通过使用synchronized关键字来保证线程安全。
在这里插入图片描述

  • 方法级别的同步:StringBuffer的方法(如append(), delete(), replace()等)都使用synchronized关键字进行同步。这意味着每个方法在执行时会获取一个对当前StringBuffer实例的锁,防止其他线程同时访问和修改对象。

  • 可变性:StringBuffer是可变类,允许在原始字符串上进行修改操作。而不像String类那样是不可变的。这可以避免在多线程环境中创建大量的临时字符串对象,减少内存开销。

  • 线程安全的追加操作:StringBuffer的append()方法是线程安全的,因为它在内部使用了同步机制。多个线程可以并发调用append()方法,确保结果正确。

尽管StringBuffer提供了线程安全的操作,但在现代的Java应用程序中,通常更倾向于使用StringBuilder类。与StringBuffer相比,StringBuilder没有同步机制,因此更高效。如果不需要在多线程环境中共享可变字符串对象,建议使用StringBuilder。如果确实需要在多线程环境中进行字符串操作,可以使用StringBuffer来保证线程安全。

Hashtable

Hashtable是Java中的一种哈希表实现,它基于数组和链表结构实现。下面介绍Hashtable的底层原理:

内部存储结构
Hashtable内部使用一个数组来保存元素,每个数组元素称为桶(bucket)。通过将键值哈希后得到索引值,在对应的桶中存储相应的值。如果多个键值映射到同一个索引上,就会在这个索引的桶上形成一个链表。

哈希函数
Hashtable使用哈希函数将键转换成整数索引,从而快速定位桶。Java默认提供了一种简单的哈希函数:hashCode()方法,可以生成32位整数类型的哈希码。

解决哈希冲突
由于不同键可能映射到相同的索引位置上,所以必须要解决哈希冲突问题。通常有两种解决办法:拉链法(Chaining)和线性探测(Linear Probing)。

拉链法:当发生哈希冲突时,在当前位置建立一个链表来存储所有键值映射到该位置上的数据。
线性探测:当发生哈希冲突时,在当前位置往后寻找下一个空槽并插入数据。
Hashtable采用了拉链法来解决哈希冲突。当多个键值映射到同一个桶上时,Hashtable会在这个桶上建立一个链表,将不同的键值对存储在链表中。

扩容
为了避免哈希冲突导致性能下降,Hashtable采用了动态扩容机制。当元素数量超过负载因子(load factor)时,默认0.75,Hashtable会自动进行扩容操作,并重新分配桶数组大小和哈希码。

线程安全
Hashtable是线程安全的,在多线程环境下可以并发访问,但是效率相对较低。因为它采用了synchronized关键字来保证线程安全。
在这里插入图片描述

Hashtable小结:

  • 方法级别的同步:Hashtable的方法(如put(), get(), remove()等)都使用synchronized关键字进行同步。这意味着每个方法在执行时会获取一个对当前Hashtable实例的锁,阻止其他线程同时访问和修改对象。

  • 互斥访问:由于synchronized关键字的存在,一次只能有一个线程访问Hashtable的方法。这种互斥访问确保了线程之间的安全性,并防止并发修改导致数据不一致的问题。

  • 内部同步机制:Hashtable使用内部锁来保护其状态。当一个线程正在执行一个方法时,其他线程会被阻塞,直到该线程完成操作。

  • 原子操作:Hashtable的方法在执行时是原子的,即一个方法的执行是不可分割的。这确保了操作的完整性,防止多个线程同时对同一个键值对进行操作。

文章到这里就先结束了,感兴趣的可以订阅专栏哈,后续会继续分享相关的知识点。

在这里插入图片描述

  • 29
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小威要向诸佬学习呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值