JUC_1_volatile 原子变量与CAS算法

1.关于JUC:

在 Java 5.0 提供了 java.util.concurrent (简称 JUC )包,在此包中增加了在并发编程中很常用 的实用工具类,用于定义类似于线程的自定义子系统,包括线程池、异步 IO 和轻量级任务框架。提供可调的、灵活的线程池。还提供了设计用于多线程上下文中的 Collection 实现等。

2.volatile 关键字:内存可见性

内存可见性:是指当某个线程正在使用对象状态而另一个线程在同时修改该状态,需要确保当一个线程修改了对象状态后,其他线程能够看到发生的状态变化。

可见性错误是指当读操作与写操作在不同的线程中执行时,我们无法确保执行读操作的线程能适时de地看到其他线程写入的值,you有时甚至是跟本不可能的事。

我们可以通过同步来保证对象被安全的发布。除此之外我们也可以使用一种更加qing轻量级的volatile变量。

volatile:java提供了一种稍弱的同步机制,即volatile变量,用来确保将变量的更新操作通知到其他线程。ke’y可以将volatile看作一个轻量级的锁,但是又与锁有些不同:                                                                                                                                                                                                         a.对于多线程,不是一种互斥关系;                                                                                                                                                      b.不能保证变量状态的原子性操作。

一个volatile案例:如果变量flag不用volatile修饰则结果为:flag=true;

                             如果变量flag用volatile修饰则结果为:flag=true
                                                                                          —————;

因为volatile 保证了内存可见性,此时main方法中的主线程识别出flag为true所以会执行打印的代码。

public class TestVolatile {

	public static void main(String[] args) {
		Demo demo = new Demo();
		new Thread(demo).start();
		
		while(true){
			//synchronized(demo){
				if(demo.isFlag()){
					System.out.println("---------------");
				break;
			}
		//}
		
	}
 }
}

class Demo implements Runnable{
	private volatile boolean flag =false;

	public void run() {
	   try {
		Thread.sleep(200);
	} catch (InterruptedException e) {
	}
		flag =true;
		System.out.println("flag="+isFlag());
	}

	public boolean isFlag() {
		return flag;
	}

	public void setFlag(boolean flag) {
		this.flag = flag;
	}
	
}

3.原子变量 CAS算法

引子:i++ 的原子性问题:i++ 的操作实际上分为三个步骤“读-改-写”
                   int i = 10;
                   i = i++; //10
  
                  int temp = i;temp为内存的值
                       i = i + 1;
                       i = temp;

        当执行一个原子性操作的时候,有的时候会读到没有经过计算的内存值,即i=i++=10.这时就需要研究这个操作的yuan原子性

3.1CAS算法:

         CAS(Compare-And-Swap)是一种硬件对并发的支持,针对多处理器操作而设计的处理器中的一种特殊的指令,用于管理dui’对贡献数据的并发fan访问。

         CAS是一种无锁的非阻塞suan算法的实现;

         CAS包含三个操作:

                  需要读写的内存值V

                  需要比较的值A

                  拟写入的新值B

当且仅当V的值等于A的值时,CAS通过原子方式用新值B来更新V的值,否则不会执行ren’任何操作。

两个Demo:

public class TestAtomicDemo {
	public static void main(String[] args) {
		//常规的int变量实现累加,结果有重复,没有保证线程安全
        //有重复的现象出现,出现的原因就是这个操作分为三步,即读,改,写;在执行这三步操作的时
        //候,没有保证一致性(原子性)提前读取了数据,之后导致重复数据的出现.
        //结果:0013256478
		AtmoicDemo ad = new AtmoicDemo();
		for(int i=0;i<10;i++){
			new Thread(ad).start();
		}
		
		try {
			Thread.currentThread().sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//原子变量实现的,结果没有重复的数字,实现了CAS的原子性
        //结果:1203475986
		AtmoicDemo2 ad2 = new AtmoicDemo2();
		for(int i =0;i<10;i++){
			new Thread(ad2).start();
		}
	}
	

}
class AtmoicDemo implements Runnable{

	private int seriaNumber;
	
	public void run() {
		try {
			Thread.currentThread().sleep(200);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("1:"+seriaNumber++);
		
	}
	
}
class AtmoicDemo2 implements Runnable{
    private AtomicInteger serNum = new AtomicInteger();
	public void run() {
		try {
			Thread.currentThread().sleep(200);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("2:"+getSerNUm());
	}
	
	public int getSerNUm(){
		return serNum.getAndIncrement();
	}
	
}

 

    原文作者:JUC
    原文地址: https://blog.csdn.net/deyu01/article/details/81983092
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞