zoukankan      html  css  js  c++  java
  • 线程安全性和共享

    概念:一般指多个并发线程对同一个类进行操作时候,这个类始终都能表现出正确的行为

    原子性:原子性一般指一系列的操作要么全部成功,要么全部失败

    • 竞态条件:由于不正确的执行顺序所造成的错误结果的情况,通常都是并发场景下对同一共享资源的读写冲突
    • 先检查后执行:由于检查和执行是两个原子性,甚至更多个原子性操作,所以会导致竞态条件的产生
    • 复合操作:即使都是原子性操作,但由于多个原子性操作的组合操作,同样会导致竞态条件的产生

    加锁机制:

    • 内置锁:Java为每个对象都支持了内部锁,synchronized默认用到了this对象的锁
    • 重入:锁的重入一般指的是A线程获取到锁之后,再次执行到同一个加锁代码,还是可以获取到此锁。不支持这种方式的话,会造成继承扩展的一些死循环。锁可以重入,也证明了锁绑定的是线程而不是调用

    锁保护状态

      锁会以一种串行的方式来执行代码,以保证状态的一致性

    活跃性与性能

      过多的同步机制会严重影响性能,但多线程不执行同步机制,极有可能导致安全性问题

    基于上面的原因:

    我们一般致力于减少同步代码的代码块,甚至不采用同步机制,一般认为有几种方案

    1、栈封闭:常见的应用就是Servlet,servlet是没有状态的,只通过一个方法来调用,也就是说所有的变量都由方法内部产生,也就是说作用域就在方法内,不存在线程共享数据问题

    2、线程封闭:ThreadLocal,线程变量。就是把一个变量和一个线程绑定在一起,可以看起来一些apache工具类中对日期格式化的代码中就用到了这个线程变量,因为SimpleDataFormat是线程不安全的类;相当于只有一个线程可以修改数据。 一般也可以通过Volatile控制变量的可见性,再通过控制仅单一线程可以修改数据来保证原子性

    3、只读对象:不可变对象和事实不可变对象,理论上只要不涉及数据的写;那么仅仅是读,就是安全的。事实不可变对象,就像是使用lombda表达式的时候,如果内部用到了外部变量,外部变量从被赋值其并未被修改,那么可以直接引用,要是被修改过值,那就必须对引用的变量进行final变量的重新引用

    4、线程安全容器:比如ConcurrentHashMap等一些线程安全的容器可以直接用于多线程调用,线程的安全性在容器内部实现,而无需在外部显示调用锁机制

    5、保护对象:即用指定的锁来保护对象,仅持有锁的线程可以访问对象

  • 相关阅读:
    文件输入输出的管理以及管道的使用
    文件权限的管理以及acl权限列表
    安装配置Linux Squid代理服务器
    安全强化机制——SELinux
    存储系统管理(二)——Linux系统的swap分区、磁盘加密、磁盘阵列
    存储系统管理(三)——磁盘配额及lvm逻辑卷管理
    存储系统管理(一)——Linux系统的设备和分区管理
    core--线程同步
    Debian字符模式下修改显示分辨率
    core--作业
  • 原文地址:https://www.cnblogs.com/gabin/p/13492029.html
Copyright © 2011-2022 走看看