volatile关键字与内存可见性&原子变量与CAS算法
Posted afangfang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了volatile关键字与内存可见性&原子变量与CAS算法相关的知识,希望对你有一定的参考价值。
1 .volatile 关键字:当多个线程进行操作共享数据时, 可以保证内存中的数据可见
2 .原子变量:jdk1.5后java.util.concurrent.atomic 包下提供常用的原子变量
3 .模拟CAS算法
TestVolatile
package com.aff.juc; /* 1.volatile 关键字:当多个线程进行操作共享数据时, 可以保证内存中的数据可见 相较于synchronized是一种较为轻量级的同步策略 注意: volatile不具备"互斥性" 不能保证变量的原子性 */ public class TestVolatile { public static void main(String[] args) { ThreadDemo td = new ThreadDemo(); new Thread(td).start(); while(true){ // synchronized (td) {//同步锁,刷新 效率极低 if(td.isFlag()){ System.out.println("------------"); break; } //} } } } class ThreadDemo implements Runnable { private volatile boolean flag = false; @Override public void run() { try { Thread.sleep(10); } catch (Exception e) { } flag = true; System.out.println("flag=" + isFlag()); } public boolean isFlag() { return flag; } }
TestAtomicDemo
package com.aff.juc; import java.util.concurrent.atomic.AtomicInteger; /* * *1. i++ 的原子性问题: i++ 操作实际上分为三步 读-改-写 * int i = 10; * i = i++;//10 * * int temp= i; * i = i +1; * i = temp; *2. 原子变量:jdk1.5后java.util.concurrent.atomic 包下提供常用的原子变量 * 1.具有volatile的特性(内存可见性) private volatile int value; * 2.CAS算法保证数据的 原子性 * CAS算法是硬件对于并发操作共享数据的支持 * CAS包含了三个操作数: * V内存值 * A预估值 * B更新值 * 当且仅当 V==A, V=B (只有当V和A相等才把B的值赋给V),否则,不做任何操作 * */ public class TestAtomicDemo { public static void main(String[] args) { AtomicDemo ad = new AtomicDemo(); new Thread(ad).start(); for (int i = 0; i < 10; i++) { new Thread(ad).start(); } } } class AtomicDemo implements Runnable { // private int serialNumber = 0; private AtomicInteger serialNumber = new AtomicInteger();// 使用原子变量 @Override public void run() { try { Thread.sleep(200); } catch (Exception e) { } //使用原子变量就不会出现重复的了 System.out.println(Thread.currentThread().getName() + ":" + getSerialNumber()); } public int getSerialNumber() { // return serialNumber++; return serialNumber.getAndIncrement(); } }
TestCompareAndSwap
package com.aff.juc; //模拟CAS算法 public class TestCompareAndSwap { public static void main(String[] args) { final CompareAndSwap cas = new CompareAndSwap(); for (int i = 0; i < 10; i++) { new Thread(new Runnable() { @Override public void run() { int expectedValue = cas.get(); // 获取内存值 boolean b = cas.compareAndSet(expectedValue, (int) (Math.random() * 100)); System.out.println(b); } }).start(); } } } class CompareAndSwap { private int value; // 获取内存值 public synchronized int get() { return value; } // 比较 public synchronized int CompareAndSwap(int expectedValue, int newValue) {// expectedValue // 预估值 int oldValue = value; if (oldValue == expectedValue) {// 旧的内存值和预估值进行比较 this.value = newValue;// 替换 } return oldValue; } // 设置 public synchronized boolean compareAndSet(int expectedValue, int newValue) { return expectedValue == CompareAndSwap(expectedValue, newValue); } }
以上是关于volatile关键字与内存可见性&原子变量与CAS算法的主要内容,如果未能解决你的问题,请参考以下文章
二:并发编程之JMM&synchronized&volatile详解
重点知识学习(8.2)--[JMM(Java内存模型),并发编程的可见性原子性有序性,volatile 关键字,保持原子性,CAS思想]