JUC--volatiley&CAS

摘要:
publicclassVolatileTest{publicstaticvoidmain(String[]args){ThreadDemotd=newThreadDemo();newThread(td).start();while(true){if(td.getFlag()){System.out.println(“==========”);break;}}}}classThreadDemimple
public class VolatileTest {
    public static void main(String[] args) {
        ThreadDemo td = new ThreadDemo();
        new Thread(td).start();
        while(true){
            if(td.getFlag()){
                System.out.println("========");
                break;
            }
        }

    }
}
class ThreadDemo implements Runnable{
   private boolean flag=false;

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

    }
    public boolean getFlag(){
        return flag;
    }
}

flag是main thread和td共享的数据,他们都在各自的线程内有一个copy,由于while true的速度十分快,main thread不能读取到td修改后的值,所以只能输出 flag=true。

内存不可见性:当多个thread操作共享数据时,彼此不可见

volatile:当多个thread操作共享数据时,保证数据是可见的,内存栅栏   可以理解为多个线程直接操作主存中的数据

因为使用vloatile 不能指令重排  所以效率低

JUC--volatiley&CAS第1张

volatile相比synchronized:

  是一种较为轻量级的同步策略,volatile不具备互斥性,两个线程可以同时访问共享数据,volatile不能保证变量的原子性,

原子性问题:i++

  JUC--volatiley&CAS第2张

以下情况使用volatile不能解决非原子性问题:内存可见性问题依然存在

public class AtomicTest {
    public static void main(String[] args) {
        AtomicDemo ad = new AtomicDemo();
        for(int i=0;i<10;i++){
            new Thread(ad).start();
        }
    }
}
class AtomicDemo implements Runnable{
    private int serialNum=0;
    @Override
    public void run() {
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+":"+getSerialNum());
    }
    public int getSerialNum(){
        return serialNum++;
    }
}

二、使用源自变量 java.util.concurrent.atomic 原子变量包

  1.使用volatile保证内存可见性

  2.使用CAS compare and swap算法保证数据的原子性

    CAS是硬件对于并发操作共享数据的支持  

    CAS包含三个操作数:

      内存值V 预估值A 更新值B

(1)首先读取内存之V 在替换的时候读取旧值A 

AtomicInteger:保证线程安全  内存可见性 原子性问题

private AtomicInteger serialNum=new AtomicInteger();
    @Override
    public void run() {
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+":"+getSerialNum());
    }
    public int getSerialNum(){
        return serialNum.getAndIncrement();
    }

 CAS算法的模拟:

public class TestCAS {
    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 expectVal = cas.get();
                    boolean b= cas.compareAndSwap(expectVal,(int)(Math.random()*101));
                }
            }).start();
        }
    }
}

class CompareAndSwap {
    private int value;
    public synchronized int get() {
        return value;
    }
    public synchronized int cas(int expectVal, int newVal) {
        int oldVal = value;
        if (oldVal == expectVal)
            this.value = newVal;
        return oldVal;
    }
    public synchronized boolean compareAndSwap(int expectVal, int newVal) {
        return  expectVal==cas(expectVal,newVal);
    }
}

免责声明:文章转载自《JUC--volatiley&amp;amp;CAS》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇【网络安全】window 快速搭建 ftp 及 多种访问方式.NET ActionFilterAttribute等下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

java----面试题

1、new String创建了几个对象 String str = "a"+"b";产生几个对象?答案是3个,字符串常量区存储"a","b","ab"三个对象 String str = "a"+new String("b");产生几个对象?答案是3个,字符串常量区存储"a","b",堆中存储new String("b")的对象。   注释:只有使用引号包含文...

cas系列-cas REST协议(三)

cas的rest协议 cas还支持rest协议方式进行访问,格式和参数如下: 1. 获取TGT     请求方式,路径,http协议及请求参数:      POST /cas/v1/tickets HTTP/1.0       username=battags&password=password&additionalParam1=param...

Java:CAS(乐观锁)

本文讲解CAS机制,主要是因为最近准备面试题,发现这个问题在面试中出现的频率非常的高,因此把自己学习过程中的一些理解记录下来,希望能对大家也有帮助。 什么是悲观锁、乐观锁?在java语言里,总有一些名词看语义跟本不明白是啥玩意儿,也就总有部分面试官拿着这样的词来忽悠面试者,以此来找优越感,其实理解清楚了,这些词也就唬不住人了。 synchronize...

2.3.7synchronized代码块有volatile同步的功能

关键字synchronized可以使多个线程访问同一个资源具有同步性,而且他还具有将线程工作内存中的私有变量与公共内存中的变量同步的功能。 package com.cky.thread; /** * Created by edison on 2017/12/9. */ public class Service { private...

CAS原子操作实现无锁及性能分析

  CAS原子操作实现无锁及性能分析 Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csdn.net/chen19870707 Date:Nov 13th, 2014 近期在研究nginx的自旋锁的时候,又见到了GCC CAS原子操作,于是决定动手分析下CAS实现的无锁究竟性能...

深入单例模式

单例模式可能是代码最少的模式了,但是少不一定意味着简单,想要用好、用对单例模式,还真得费一番脑筋。本文对Java中常见的单例模式写法做了一个总结,如有错漏之处,恳请读者指正。 饿汉法 顾名思义,饿汉法就是在第一次引用该类的时候就创建对象实例,而不管实际是否需要创建。代码如下: public class Singleton { private...