• 线程安全性和共享


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

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

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

    加锁机制:

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

    锁保护状态

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

    活跃性与性能

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

    基于上面的原因:

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

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

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

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

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

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

  • 相关阅读:
    又搬回来了233
    2017.10.2解题报告
    2017.10.1解题报告
    Android 百度地图开发(二)--- 定位功能之MyLocationOverlay,PopupOverlay的使用
    Last_IO_Errno: 1236 Last_IO_Error: Got fatal error 1236 from master when reading data from binary lo
    [Warning] Aborted connection 11203 to db: 'ide' user: 'nuc' host: 'prd01.mb.com' (Got an error writi
    浅析地方门户网优化的方法
    xxx==null和xxx.equals(null)的区别
    Java+7入门经典
    《UNIX环境高级编程》笔记--read函数,write函数,lseek函数
  • 原文地址:https://www.cnblogs.com/gabin/p/13492029.html
Copyright © 2020-2023  润新知