java基础之线程安全问题以及线程安全集合类

这篇具有很好参考价值的文章主要介绍了java基础之线程安全问题以及线程安全集合类。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

线程安全问题

  • 当多个线程同时访问同一个临界资源时,原子操作可能被破坏,会导致数据丢失, 就会触发线程安全问题

    • 临界资源: 被多个线程同时访问的对象

    • 原子操作: 线程访问临界资源的过程中不可更改和缺失的操作

互斥锁

  • 每个对象都默认拥有互斥锁, 该锁默认不开启.

  • 当开启互斥锁之后,线程想要访问对象,则在需要拥有时间片的基础上也拥有锁标记,锁标记只能被一个线程拥有,拥有时间片和锁标记的线程才能执行自身内容,在此期间,其他线程只能等正在执行的线程执行结束释放锁标记和时间片之后才能进入就绪状态

  • synchronized: 开启互斥锁的关键字

同步方法
  • 思路: 在被线程同时访问的方法上加锁

    访问修饰符 synchronized 返回值类型 方法名(参数列表){   
    
      }
    
    package com.by.util;
    ​
    import java.util.ArrayList;
    import java.util.List;
    ​
    /**
     * 工具类-操作集合属性
     */
    public class MyList {
        private List<Integer> list = new ArrayList<>();
    ​
        /**
         * 给集合属性添加元素
         * @param n 添加的元素值
         synchronized: 同步方法
         */
        public synchronized void insert(int n){
            list.add(n);
        }
        /**
         * 查看集合内容
         */
        public void query(){
            System.out.println("集合长度: " + list.size());
            for (int i = 0; i < list.size(); i++) {
                System.out.print(list.get(i)+"  ");
            }
        }
    ​
    }
同步代码块
  • 思路: 让参与临界资源对象访问的线程自身加锁

    synchronized(临界资源对象){    //需要被认定为原子操作的代码 }
    
  • 使用: 所有访问同一临界资源的线程都需要同时添加同步代码块

    package com.by.test2;
    ​
    import com.by.util.MyList;
    ​
    public class TestMyList {
        public static void main(String[] args)throws Exception {
            //创建两个线程,同时操作工具类,线程1负责往集合中添加元素1-5,线程2负责往集合中添加元素6-10
            //添加结束之后查看集合内容
            //创建工具类对象
            MyList m = new MyList();
            Thread t1=new Thread(()->{
                for (int i = 1; i <=5 ; i++) {
                    synchronized (m) {
                        m.insert(i);
                    }
                }
            });
    ​
            Thread t2=new Thread(()->{
                for (int i = 6; i <=10 ; i++) {
                    synchronized (m) {
                        m.insert(i);
                    }
                }
            });
    ​
            t1.start();
            t2.start();
            //使t1和t2线程先进行添加操作
            t1.join();
            t2.join();
    ​
            //查看集合元素
            m.query();
        }
    }
    ​
    ​
    /*
    * 张三上厕所
    * 李四上厕所
    *
    * 原子操作: 脱裤子-->蹲下来-->上厕所-->擦屁股-->穿裤子-->冲水-->走人
    *
    *临界资源: 厕所-坑位
    *
    *解决方式1:给厕所大门加锁
    *解决方式2:自己给坑位加锁
    * 
    *
    * */
区别
  1. 同步方法: 线程执行需要同时争抢时间片和锁标记,写法简单但效率较慢

  2. 同步代码块: 线程只需要争抢时间片, 开启互斥锁的线程默认拥有锁标记, 效率较快但写法相对繁琐

线程安全的集合类

悲观锁: 悲观的认为集合一定会出现线程安全问题,所以直接加锁

乐观锁: 乐观的认为集合一定不会出现线程安全问题,如果安全问题发生,再利用算法解决问题(无锁机制)

JDK5.0,发布了一批无锁机制的线程安全的集合类

都来自于java.util.concurrent包

  1. ConcurrentHashMap: CAS算法

    compare and swap: 比较并交换

    原有值,预期值,结果值: 当原有值与预期值相等时才会将结果值放入内存

    int i=1;

    i++;

    原有值: 1 预期值: 1 结果值:2

  2. CopyOnWriteArrayList:

    • 当集合进行写(增删改)操作时,会先复制出一个副本,在副本中进行写操作,如果过程中出现线程安全问题,则舍弃当前副本,重新复制新的副本重复操作,直至副本中无异常,再将集合引用地址转换向副本地址,一次确保原集合中一定不会发生安全问题

    • 特点: 舍弃写的效率提高读的效率,适用于读操作远多于写操作时

  3. CopyOnWriteArraySet:

    • 原理与CopyOnWriteArrayList一致, 在写时会对元素进行去重

掌握

  1. 什么是线程安全问题?

  2. 如何解决线程安全问题

  3. 同步方法和同步代码块的区别

  4. 线程安全的集合类及原理文章来源地址https://www.toymoban.com/news/detail-802766.html

到了这里,关于java基础之线程安全问题以及线程安全集合类的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • JUC并发编程-集合不安全情况以及Callable线程创建方式

    1)List 不安全 ArrayList 在并发情况下是不安全的 解决方案 : 1.Vector 2.Collections.synchonizedList() 3. CopyOnWriteArrayList 核心思想 是,如果有 多个调用者(Callers)同时要求相同的资源 (如内存或者是磁盘上的数据存储),他们 会共同获取相同的指针指向相同的资源 , 直到某个调用者

    2024年01月23日
    浏览(34)
  • Java 多线程之线程安全集合

    集合关系图 本文主要关注线程安全的集合,如 List、Set、Queue、Map 等接口的线程安全的实现方式,有关集合基础知识请转到这里。所谓线程安全集合,就是在多线程环境中使用集合不会导致数据不一致和数据异常的集合。在 Java 中线程安全集现在基本都使用 java.util.concurrent

    2024年02月05日
    浏览(31)
  • 从零学Java 线程安全的集合

    Collection体系集合、以及线程安全集合。 注:下划线代表线程安全集合 Collections中的工具方法 Collections工具类中提供了多个可以获得线程安全集合的方法。 public static Collection synchronizedCollection(Collection c) public static List synchronizedList(List list) public static Set synchronizedSet(Set s) public

    2024年01月17日
    浏览(22)
  • Java 8并发集合:安全高效的多线程集合

    在多线程环境中,使用线程安全的数据结构非常重要,以避免竞态条件和数据不一致的问题。Java 8引入了一些并发集合类,提供了安全高效的多线程集合操作。本教程将介绍Java 8中的并发集合类,包括ConcurrentHashMap、ConcurrentLinkedQueue、ConcurrentSkipListSet和CopyOnWriteArrayList。 Conc

    2024年02月04日
    浏览(37)
  • 【JAVA】哪些集合类是线程安全的

    🍎 个人博客: 个人主页 🏆 个人专栏: JAVA ⛳️   功不唐捐,玉汝于成 目录 前言 正文 Vector: HashTable: Collections.synchronizedList()、Collections.synchronizedSet()、Collections.synchronizedMap(): 4.ConcurrentHashMap: 5.CopyOnWriteArrayList 和 CopyOnWriteArraySet: 结语  我的其他博客 在多线程编程中

    2024年01月25日
    浏览(26)
  • JAVA数据结构篇--13线程安全的Set 集合

    前言:java 中用于存放不重复元素的set 集合,其中无序的HashSet,以及有序的LinkedHashSet和TreeSet 都是非线程安全的,那么多线程环境下,我们要存放不重复的元素,需要使用哪种集合进行数据存取; 1 使用: 2 过程: 2.1 放入获取元素: Collections.synchronizedSet:通过使用synchron

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

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

    2024年02月05日
    浏览(26)
  • 再谈StringBuilder为什么线程不安全以及带来的问题

    比较有意思的是,学习锁消除的过程中,有人讲到StringBuffer在方法内构建,不会被其他方法引用时,StringBuffer的锁会被消除, 于是,顺便看了一下同源的StringBuidler为什么线程不安全,以及为什么多线程不安全,和带来的问题, 有了这篇文章,分享出来,帮助读者轻松应对知

    2024年02月11日
    浏览(29)
  • Java多线程 - 线程安全和线程同步解决线程安全问题

    线程安全问题指的是: 多个线程同时操作同一个共享资源的时候可能会出现业务安全问题,称为线程安全问题。 举例: 取钱模型演示 需求:小明和小红是一对夫妻,他们有一个共同的账户,余额是10万元。 如果小明和小红同时来取钱,而且2人都要取钱10万元,可能出现什么问

    2023年04月15日
    浏览(26)
  • Java多线程之线程安全问题

    我们知道操作系统中线程程的调度是抢占式执行的, 宏观上上的感知是随机的, 这就导致了多线程在进行线程调度时线程的执行顺序是不确定的, 因此多线程情况下的代码的执行顺序可能就会有无数种, 我们需要保证这无数种线程调度顺序的情况下, 代码的执行结果都是正确的

    2023年04月17日
    浏览(31)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包