关于线程安全的涉及到概念以及分类
来源:互联网 发布:python需要设计模式吗 编辑:程序博客网 时间:2024/06/05 20:22
本文摘选自深入理解Java虚拟机。
方法一:互斥同步(Matual Exclusion & Synchronization)
①使用synchronized关键字。synchronized同步代码块对同一个线程来说是可重入的,不会出现自己吧把自己锁死的问题。
②使用ReentrantLock重入锁来实现同步。ReentrantLock与synchronized很相似。都是对同一个线程可重入。不过ReentrantLock增加了一些高级的功能:等待可中断,可实现公平锁。锁可以绑定多个条件。
等待可中断是指:当持有锁的线程长期不释放锁的时候,正在等待的线程可以选择放弃等待。改为处理其他事情,可中断特性对处理执行时间非常长的同步块很有帮助。
公平锁:多个线程在等待同一个锁时,必须按照申请锁的时间顺序来依次获得锁。而非公平锁不保证这一点:在锁被释放的时候,任何一个等待锁的线程都有机会获得锁(通过竞争获得锁)。synchronized中的锁是非公平锁,ReentrantLock默认情况下也是非公平锁,但是可以通过带布尔值的构造函数来构造公平锁。
锁绑定多个条件是指一个ReentrantLock对象可以同时绑定多个Condition对象。在synchronized中,隐含着绑定一个对象,如果要是有多个对象关联的时候,就要多加一个额外的锁。ReentrantLock则不需要这样做,只需要多次调用newCondition()方法即可。
方法二:非阻塞同步(又称乐观锁)
互斥同步最主要的问题就是进行线程阻塞和唤醒所带来的性能问题,因此这种同步也称为阻塞同步(Blocking Synchronization)。所以就有了一种不需把线程挂起的同步操作称之为非阻塞同步(Non-Blocking Synchronization):一种基于冲突检测的乐观并发策略,通俗了说,就是先进行操作,如果没有其他线程争用共享数据,那操作就成功了;如果共享数据有争用,产生了冲突,那就采用其他的补偿措施(最常见的的就是不断重试,直到成功为止)。在Java中常见的就是Compare-and Swap(CAS)指令。CAS指令有三个操作数,分别是内存位置的值(用V表示),旧的预期值A,新值B,CAS指令执行的时候,当且仅当V符合旧预期值A时,处理器用新值B更新V的值,否则 就不执行更新,无论是否更新V的值,都会返回V的旧值。
CAS指令这个执行过程是个原子操作。其他的原子操作还有指令:测试并设置(Test- And-Set)、获取并增加(Fetch-And-Increment)、交换(Swap)、加载链接/条件存储(Load-Linked/Store-Conditional)。
方法三:无同步方案
如果一个方法本来就不涉及共享数据,那它自然就不需要任何同步措施去保证正确性,因此会有一些代码天生就是线程安全的。
一类:可重入代码(Reentrant Code):这种代码叫做纯代码,可以在代码执行的任何时刻去中断它,转而去执行另一段代码,而在控制权返回后,原来的程序不会出现任何错误。判断是否可重入性的原则:如果一个方法,他的返回结果是可以预测的,只要输入了相同的数据,就能返回相同的结果,那它就满足可重入性的要求。
二类:线程本地存储(Thread Local Storage):如果一段代码中所需要的数据必须与其他代码共享数据。如果能保证这些共享数据的代码在同一个线程中执行,那么这些共享数据的可见范围在同一个线程之内。这样不需要同步也能保证线程之间不出现数据争用的问题。在Java中,通过java.lang.ThreadLocal 类来实现线程本地存储的功能。
- 关于线程安全的涉及到概念以及分类
- 可重入、异步信号安全以及线程安全的概念
- 线程安全的概念
- 关于线程安全的记录以及python GIL
- 关于Django的配置思路以及涉及到的知识
- C++中涉及到的概念
- 关于线程安全以及nonatomic和atomic
- Qt可重入的线程安全的概念
- 可重入和线程安全的概念
- 关于线程的 一些概念
- 题型:涉及到i++的用法,变量作用域以及闭包的概念
- 关于线程安全的笔记
- 线程安全概念
- 什么是线程安全以及threadlocal为什么是线程安全的
- 线程函数的可重入性和线程安全的概念
- 并发的概念以及线程的控制
- 关于图像处理中所涉及到的一些边缘概念及名词解析
- PHP关于VC9和VC6的区别以及是否线程安全的版本选择
- 动态创建元素如何绑定事件
- leetcode解题方案--045-- Jump Game II
- 使用Jenkins持续集成JavaWeb项目(War包部署方式)
- Check failed: proto.SerializeToOstream(&output)
- MyBatis动态SQL之增、删、改、查操作
- 关于线程安全的涉及到概念以及分类
- 我在github的项目网址
- 欢迎使用CSDN-markdown编辑器
- ExtJs之gridPanel
- 【OpenCV入门教程之十五】水漫金山:OpenCV漫水填充算法(Floodfill)
- java虚拟机运行实例
- 文章标题
- pappet运维应用(一)
- 模型融合