zoukankan      html  css  js  c++  java
  • 十一、并发安全

    并发安全

    【1】什么是类的线程安全?

    ​ 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在调用代码中不需要任何额外的同步或者协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的。

    【2】线程不安全引发的问题

    死锁
    死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁。

    ​ 解决:保证加锁的有序性

    动态顺序死锁

    动态顺序死锁是在实现时按照某种顺序加锁了,但是因为外部调用的问题,导致无法保证加锁顺序而产生的。

    解决方法:

    1)通过内在排序,保证加锁的顺序性(使用identityHashCode获得原生的hashcode,按照这个的hashcode大小制定加锁顺序);

    2)通过显示锁tryLock()进行尝试拿锁

    活锁

    尝试拿锁的机制中,发生多个线程之间互相谦让,不断发生拿锁,释放锁的过程。

    解决办法:每个线程休眠随机数,错开拿锁的时间。

    线程饥饿

    【3】怎么才能做到类的线程安全?

    栈封闭
    所有的变量都是在方法内部声明和使用,这些变量都处于栈封闭状态。

    无状态类

    没有任何成员变量的类,就叫无状态的类

    让类不可变

    让类不可变有两种方法:

    • 加final关键字,对于一个类,所有的成员变量应该是私有的,同样的只要有可能,所有的成员变量应该加上final关键字,但是加上final,要注意如果成员变量又是一个对象的引用时,这个对象所对应的类也要是不可变,才能保证整个类是不可变
    • 不提供修改成员变量的方法,同时成员变量也不作为方法的返回值

    volatile

    保证类的可见性,最适合一个线程写,多个线程读的情景

    对于写,可以使用Synchronized加锁等效为一个线程写

    加锁和CAS

    详情见往期博客

    安全的发布

    类中持有的成员变量,特别是对象的引用,如果这个成员对象不是线程安全的,通过get等方法发布出去,会造成这个成员对象本身持有的数据在多线程下不正确的修改,从而造成整个类线程不安全的问题。

    解决方法:

    • 用线程安全的容器替换
    • 返回副本,深拷贝
    • 加锁

    TheadLocal

    详情见往期博客

    【4】线程安全的单例模式

    饿汉式

    • 在声明的时候就new这个类的实例,因为在JVM中,对类的加载和类初始化由虚拟机保证线程安全。
    public class SingletonHungry {
        public static SingletonHungry singletonHungry = new SingletonHungry();
        private SingletonHungry(){}
    }
    
    • 或者使用枚举。

    懒汉式
    在单例类的内部由一个私有静态内部类来持有这个单例类的实例。

    public class SingletonLazy {
        private SingletonLazy(){}
    
        //定义一个私有类,来持有当前类的实例
        private static class InstanceHolder{
            public static SingletonLazy instance = new SingletonLazy();
        }
    
        public static SingletonLazy getInstance(){
            return InstanceHolder.instance;
        }
    }
    
  • 相关阅读:
    C++中的空类默认产生哪些类成员函数
    Berkeley Socket API – Creating a TCP/IP client in C
    覆盖父类以及using指令
    strcpy/memcpy/memmove的实现
    [C++对象模型][1]目录与参考
    用setsockopt()来控制recv()与send()的超时
    异常安全的赋值运算符重载函数
    伤不起的指针
    DP01背包
    证明一个数能被3整除,当且仅当它的各位数的和能被3整除
  • 原文地址:https://www.cnblogs.com/lee0527/p/11723051.html
Copyright © 2011-2022 走看看