线程安全的实现方法
线程安全的实现方法
1、互斥同步
互斥同步是最常见的一种并发正确性保障手段。同步是指在多个线程并发访问共享数据时,保证共享数据在同一时刻只能被一个线程使用。而互斥是实现同步的一种手段,临界区、互斥量和信号量都是主要的互斥实现方式。互斥是方法,同步时目的。
2、非阻塞同步
互斥同步最主要的问题就是进行线程阻塞和唤醒所带来的性能问题,因此这种同步也成为阻塞同步。从处理问题的方式上说,互斥同步属于一种悲观的并发策略,总是认为只要不去做正确的同步措施(例如加锁),那就会出现问题。
随着硬件指令集的发展(比如,现代处理器对CAS(Compare and Swap)指令的支持),我们有了另一个选择:基于冲突检测的乐观并发策略,通俗的讲,就是先进行操作,如果没有其他线程争用共享数据,那操作就成功了。如果共享数据有争用,产生了冲突,那就再采取其他的补偿措施(最常见的补偿措施就是不断的尝试,直到成功为止),这种乐观的并发策略的许多实现都不需要把线程挂起,因此这种同步操作称为非阻塞同步。
3、无同步方案
要保证线程安全,并不是一定就要进行同步,两者没有因果关系。同步只是保证共享数据争用时的正确性的手段,如果一个方法不涉及共享数据,那它自然就无需任何同步措施保证正确性。
可重入代码:可重入代码有一些共同的特征,例如不依赖存储在堆上的数据和公共的系统资源、用到的状态量都由参数传入、不调用不可重入方法等。如果一个方法,它的返回结果是可预测的,只要输入了相同的数据,就都能返回相同的结果,就是可重入的。
线程本地存储:如果一段代码中所需要的数据必须与其他代码共享,那就看看这些共享数据的代码是否能保证在同一个线程中执行?如果能保证,我们就可以把共享数据的可见范围限定在同一个线程之内,这样就无须同步也能保证线程之间不出现数据争用的问题。例如,Web交互模式中的“一个请求对应一个服务器线程”的处理方式,这种处理方式使得很多Web服务端应用都可以使用线程本地存储来解决线程安全问题。例如,ThreadLocal在Spring事务管理中的应用。
- 点赞
- 收藏
- 关注作者
评论(0)