多线程环境下如何安全的使用线性表, 队列, 哈希表

这篇具有很好参考价值的文章主要介绍了多线程环境下如何安全的使用线性表, 队列, 哈希表。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

今日鸡汤

内心丰盈者, 独行也如众

安全使用ArrayList

  1. 使用synchronized锁或者reentrantLock锁
  2. 使用CopyOnWriteArrayList(COW写时拷贝)类来代替ArrayList类.
  1. 多个线程对CopyOnWriteArrayList里面的ArrayList进行读操作, 不会发生线程安全问题, 不做任何处理
  2. 多个线程对CopyOnWriteArrayList里面的ArrayList进行写操作, 会为每个线程创建一个副本, 各个线程在各自独立的副本上进行修改, 最后不会进行汇总, 最后一个完成写操作的副本将会代替旧的ArrayList(牺牲了实时性来确保线程安全). 如果在写操作期间有线程对其进行读操作, 会读旧的(修改之前的)ArrayList. 本质上是引用之间的赋值. 这种方法适用于读频繁, 不经常写入的情况. 如服务器的配置文件.
  3. CopyOnWriteArrayList的局限性在于:
    (1) 牺牲了实时性, 同时多个线程进行写操作时之会将最后一个完成写操作的副本代替原来的ArrayList, 而率先完成写操作的副本将会作废, 也因此这种方法只适用于读频繁而不经常写的情况
    (2) 这种方法也只适用于ArrayList较小的情况, 否则在创建副本时将会付出巨大的开销.
    (3) 服务器的配置文件就是采用这种写时拷贝的方式来对配置文件进行修改的, 这个功能叫热加载

安全使用队列

  1. 基于数组实现的阻塞队列
ArrayBlockingQueue
  1. 基于链表实现的阻塞队列
LinkedBlockingQueue
  1. 基于堆实现的带优先级的阻塞队列
PriorityBlockingQueue
  1. 最多只包含一个元素的阻塞队列
TransferQueue

安全使用HashMap

  1. 使用HasHTable代替HashMap, HashTable中的关键方法进行了上锁, 使用时是线程安全的
  2. 使用ConcurrentHashMap代替HashMap

ConcurrentHashMap和HashTable的区别:文章来源地址https://www.toymoban.com/news/detail-722141.html

  1. ConcurrentHashMap的锁粒度更小, 锁冲突发生的概率小.
    HashTable的锁对象是整个哈希表, 这就意味着对哈希表中的任何元素进行操作都会上锁, 但是有些操作是不需要上锁的.
    多线程环境下如何安全的使用线性表, 队列, 哈希表,操作系统,安全,散列表,数据结构,操作系统,多线程,线程安全,java而ConcurrentHashMap的锁对象是单个链表, 这就大大细化了锁的粒度, 大大减小了发生锁冲突的概率, 且提高了性能
    多线程环境下如何安全的使用线性表, 队列, 哈希表,操作系统,安全,散列表,数据结构,操作系统,多线程,线程安全,java
  2. ConcurrentHashMap对读操作不上锁, 只对写操作上锁. 通过volatile关键字+原子操作写来确保边读边写的线程安全, 避免脏读的发生.
  3. ConcurrentHashMap使用了CAS操作, 尽量减少上锁的操作. 提高并发性能.
  4. 扩容方面, ConcurrentHampMap使用了化整为零的方式.
    (1) HashTable在进行扩容时, 容量扩为原来的两倍, 将原哈希表中的数据复制到新表中, 因为其是对整个哈希表上锁, 所以在整个哈希表未完成扩容时, 对其的读写操作都会陷入阻塞, 这大大降低了性能. 由于扩容是在put时发生的, 所以会造成某次put操作非常慢.
    (2) ConcurrentHashMap在扩容时, 由于锁对象是链表, 所以在进行数据迁移时, 各个链表可以独立迁移, 这样在一次迁移中只对正在迁移的链表上锁, 针对其他链表的读写操作还可以执行. 每一次put操作只迁移一部分数据, 这会造成在一段时间内就哈希表和新哈希表共存的情况, 迁移时将链表节点从旧表删除, 在新表中插入
    如果要执行put操作, 则直接在新的哈希表中添加
    如果要执行take操作, 则对原哈希表和新哈希表都进行检索
    直到新哈希表扩容完成(数据全部迁移), 再释放旧的哈希表.

到了这里,关于多线程环境下如何安全的使用线性表, 队列, 哈希表的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Qt QQueue 安全的多线程队列、阻塞队列

    在C++中,queue是一个模板类,用于实现队列数据结构,遵循先进先出的原则。 ♦ 常用方法: · ♦ 简单使用: · ♦ 打印: · QQueue 继承与 QList ♦ 常用方法: · ♦ 实例: · ♦ 打印: · 在多线程编程中,由于QQueue并不是线程安全的,因此我们需要先使用互斥锁(QMutex)来保

    2024年02月16日
    浏览(25)
  • C++:设计一个线程安全的队列

    串行的程序只用到单个 CPU 核心, 希望加速整个程序, 考虑使用多线程加速。典型情况下可以找到生产者、消费者,两个角色之间通过队列进行数据交互: 生产者负责把数据放入队列Q 消费者负责从队列取出数据Q 要求队列是线程安全的,即:不能有读写冲突等。 这里并不给

    2024年02月14日
    浏览(30)
  • Java - JUC(java.util.concurrent)包详解,其下的锁、安全集合类、线程池相关、线程创建相关和线程辅助类、阻塞队列

    JUC是java.util.concurrent包的简称,在Java5.0添加,目的就是为了更好的支持高并发任务。让开发者进行多线程编程时减少竞争条件和死锁的问题 java.lang.Thread.State tools(工具类):又叫信号量三组工具类,包含有 CountDownLatch(闭锁) 是一个同步辅助类,在完成一组正在其他线程中

    2024年02月05日
    浏览(29)
  • Vant 弹出列表多选 输入框下拉选择 (可直接复制使用)

    项目要做移动端,部分功能迁移过程中发现,VantUI组件库不支持原Element组件库的部分功能,例如el-select 可以做到输入的同时下拉选择 下拉多选。 故需要手动改写,分享记录下代码。 效果图

    2024年02月11日
    浏览(53)
  • Java线程队列的使用-PriorityBlockingQueue

    PriorityBlockingQueue是一种带优先级的无界阻塞队列,它的元素必须实现Comparable接口,或者在创建时指定一个Comparator对象。它会根据元素的优先级顺序进行排序,优先级高的元素先被获取。 PriorityBlockingQueue可以用于实现优先级任务调度,例如下面的代码创建了一个PriorityBlockin

    2024年02月11日
    浏览(34)
  • 【多线程】Java如何实现多线程?如何保证线程安全?如何自定义线程池?

    个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ 线程 : 线程是操作系统能够进行运算调度的最小单位。它被包含在进程中,是进程中的实际运作单位。 生

    2024年02月08日
    浏览(48)
  • ArrayList为什么不是线程安全的,如何保证线程安全?

    官方曰, 线程安全就是多线程访问时,采⽤了加锁机制,当⼀个线程访问该类的某个数据时,进⾏保护,其他线程不能进⾏访问直到该线程读取完,其他线程才可使⽤。不会出现数据不⼀致或者数据污染。线程不安全就是不提供数据访问保护,有可能出现多个线程先后更改数

    2024年02月07日
    浏览(50)
  • 如何确保线程安全?

    如何确保线程安全? 在 Java 中可以有很多方法来保证线程安全——同步,使用原子类(atomic concurrent classes),实现并发锁,使用 volatile ,使用不变类和线程安 全类。 73、同步方法和同步块,哪个是更好的选择? 同步块是更好的选择,因为它不会锁住整个对象(当然你也

    2023年04月12日
    浏览(29)
  • Hashmap如何保证线程安全

    本文介绍Java中的HashMap如何进行线程安全的操作、为什么HashMap不是线程安全的。 线程安全Map的三种方法 方法 示例 原理 性能 HashTable MapString, Object map = new Hashtable(); synchronized修饰get/put方法。方法级阻塞,只能同时一个线程操作get或put 很差。 Collections.synchronizedMap MapString, Obj

    2023年04月16日
    浏览(42)
  • Swift如何保证线程安全

    Swift可以通过以下几种方式来保证线程安全 使用互斥锁(Mutex):使用互斥锁可以防止多个线程同时访问共享数据,保证线程安全。 使用OSAtomic操作:OSAtomic操作可以在多线程环境中安全地执行原子操作。 使用DispatchQueue:DispatchQueue可以使用GCD技术实现线程安全。您可以使用

    2024年02月13日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包