• 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);
        }
    }
    All that work will definitely pay off
  • 相关阅读:
    HDU3480-Division-斜率dp
    CDQ题目套路总结 [未完成]
    HDU5773-The All-purpose Zero-多校#41010-最长上升子序列问题
    POJ2763-Housewife Wind-树上单点修改区间求和
    HDU3507-Print Article-斜率dp入门题
    POJ2187-Beauty Contest-凸包
    SPOJ QTREE-Query on a tree-树链剖分-边权
    扫描系统进程和获取某进程的PID
    ConfuserEx壳
    关于Intel漏洞的学习
  • 原文地址:https://www.cnblogs.com/afangfang/p/12630628.html
Copyright © 2020-2023  润新知