多线程2

时间:2021-06-08 23:17:33   收藏:0   阅读:0

volatile

作用

图解说明:

技术图片

A B线程都用到一个变量,java默认是A线程中保留一份copy,这样如果B线程修改了该变量,则A线程未必知道,不知B线程何时去修改真正的变量的值,此时使用volatile关键字,会让所有线程都会读到变量的修改值

volatie和synchronized区别

volatile其他

  1. volatile 引用类型(包括数组)只能保证引用本身的可见性,不能保证内部字段的可见性。

    public class T04_VolatileNotSync {
    	volatile int count = 0;
    	void m() {
    		for(int i=0; i<10000; i++) count++;
    	}
    	
    	public static void main(String[] args) {
    		T04_VolatileNotSync t = new T04_VolatileNotSync();
    		
    		List<Thread> threads = new ArrayList<Thread>();
    		
    		for(int i=0; i<10; i++) {
    			threads.add(new Thread(t::m, "thread-"+i));
    		}
    		
    		threads.forEach((o)->o.start());
    		
    		threads.forEach((o)->{
    			try {
    				o.join();
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		});
    		
    		System.out.println(t.count);
    		
    		
    	}
    	
    }
    
    =============
     输出结果的原因是:volatile虽然能够保证count的可见性,但是不能够保障count++的原子性
    

    输出结果

    技术图片

CAS(compare and swap)

什么是CAS

CAS:Compare and Swap,即比较再交换。

jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronouse同步锁的一种乐观锁。JDK 5之前Java语言是靠synchronized关键字保证同步的,这是一种独占锁,也是是悲观锁。

CAS属于CPU原语级别的支持,正常程序不会被打断

CAS算法理解

CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。

技术图片

CAS实现原理

CAS缺点

循环时间长开销很大:

CAS 通常是配合无限循环一起使用的,我们可以看到 getAndAddInt 方法执行时,如果 CAS 失败,会一直进行尝试。如果 CAS 长时间一直不成功,可能会给 CPU 带来很大的开销。

只能保证一个变量的原子操作:

当对一个变量执行操作时,我们可以使用循环 CAS 的方式来保证原子操作,但是对多个变量操作时,CAS 目前无法直接保证操作的原子性。但是我们可以通过以下两种办法来解决:1)使用互斥锁来保证原子性;2)将多个变量封装成对象,通过 AtomicReference 来保证原子性。

什么是ABA问题?ABA问题怎么解决?

CAS 的使用流程通常如下:
1)首先从地址 V 读取值 A;
2)根据 A 计算目标值 B;
3)通过 CAS 以原子的方式将地址 V 中的值从 A 修改为 B。

但是在第1步中读取的值是A,并且在第3步修改成功了,我们就能说它的值在第1步和第3步之间没有被其他线程改变过了吗?

如果在这段期间它的值曾经被改成了B,后来又被改回为A,那CAS操作就会误认为它从来没有被改变过。这个漏洞称为CAS操作的“ABA”问题。Java并发包为了解决这个问题,提供了一个带有标记的类“AtomicStampedReference”,它可以通过控制变量值的版本来保证CAS的正确性。因此,在使用CAS前要考虑清楚“ABA”问题是否会影响程序并发的正确性,如果需要解决ABA问题,改用传统的互斥同步可能会比原子类更高效。

AutomicXXX(CAS+ volatile)

相关概念

代码详解

主要以AtomicInteger为例

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!