zoukankan      html  css  js  c++  java
  • 关于线程安全学习笔记

    1、什么是线程安全

    线程安全不是线程的安全,而是堆内存的安全

    在堆内存中的数据由于可以被任何线程访问到,在没有限制的情况下存在被意外修改的风险

    即堆内存空间在没有保护机制的情况下,对多线程来说是不安全的地方,因为你放进去的数据,可能被别的线程“破坏”

    2、实现线程安全的解决方案

    位置:定义私有变量,仅本线程可访问 保障线程安全

    复制:ThreadLocal,线程本地,每个线程拷贝一份数据到在自己线程下,实现互不干扰 

    class StudentAssistant {
    
        ThreadLocal<String> realName = new ThreadLocal<>();
        ThreadLocal<Double> totalScore = new ThreadLocal<>();
    
        String determineDegree() {
            double score = totalScore.get();
            if (score >= 90) {
                return "A";
            }
            if (score >= 80) {
                return "B";
            }
            if (score >= 70) {
                return "C";
            }
            if (score >= 60) {
                return "D";
            }
            return "E";
        }
    
        double determineOptionalcourseScore() {
            double score = totalScore.get();
            if (score >= 90) {
                return 10;
            }
            if (score >= 80) {
                return 20;
            }
            if (score >= 70) {
                return 30;
            }
            if (score >= 60) {
                return 40;
            }
            return 60;
        }
    }

    Final:  只能看不能摸,只能读取,不能修改。其实就是常量或只读变量

    class StudentAssistant {
        final double passScore = 60;
    }

    加锁:悲观锁,即默认所有都可能出现线程安全,加锁,其他线程若修改需取到锁 查锁状态,锁未释放只能等候或处理转而处理其他问题

     1 class ClassAssistant {
     2 
     3     double totalScore = 60;
     4     final Lock lock = new Lock();
     5 
     6     void addScore(double score) {
     7         lock.obtain();
     8         totalScore += score;
     9         lock.release();
    10     }
    11 
    12     void subScore(double score) {
    13         lock.obtain();
    14         totalScore -= score;
    15         lock.release();
    16     }
    17 }

    CAS: 乐观锁,即默认都会出现线程安全问题,防止ABA问题,加上 版本号,对比当前数据与线程取到的数据,版本号未变线程数安全数据未修改,否则放弃重来

    3、引用大神总结:

    前两种属于隔离法,一个是位置隔离,一个是数据隔离。

    然后两种是标记法,一个是只读标记,一个是加锁标记。

    最后一种是大胆法,先来怼一把试试,若不行从头再来。

    参考文档 https://www.cnblogs.com/lixinjie/p/10817860.html

  • 相关阅读:
    Fix Installing .NET Framework 3.5 failed Error Code 0x800F0954 on Windows 10
    RHEL8安装五笔输入法
    Enable EPEL and Local Repository on RHEL8
    Why is Yum Replaced by DNF?
    检查Linux服务器是否被攻击的常用命令及方法
    IDEA 主题
    IDEA 如何显示一个类中所有的方法
    Appium 安装以及安装过程中遇到的问题
    Maven 如何发布 jar 包到 Nexus 私库
    java泛型的基本使用
  • 原文地址:https://www.cnblogs.com/0819lsl/p/11009727.html
Copyright © 2011-2022 走看看