• 原子变量与CAS算法


    原子变量

    为了引出原子变量这个概念,我们先看一个例子。

     1 package com.ccfdod.juc;
     2 
     3 public class TestAtomicDemo {
     4 
     5     public static void main(String[] args) {
     6         AtomicDemo ad = new AtomicDemo();
     7         
     8         for (int i = 0; i < 10; i++) {
     9             new Thread(ad).start();
    10         }
    11     }
    12 }
    13 
    14 class AtomicDemo implements Runnable {
    15     private int number = 0;
    16 
    17     @Override
    18     public void run() {
    19         try {
    20             Thread.sleep(200);
    21         } catch (InterruptedException e) {
    22             e.printStackTrace();
    23         }
    24         System.out.println(Thread.currentThread().getName() + " : " + getNumber());
    25     }
    26     
    27     public int getNumber() {
    28         return number++;
    29     }
    30 }

    程序运行结果如下:

     1 Thread-4 : 2
     2 Thread-0 : 6
     3 Thread-2 : 3
     4 Thread-5 : 5
     5 Thread-7 : 4
     6 Thread-3 : 1
     7 Thread-6 : 2
     8 Thread-1 : 0
     9 Thread-9 : 8
    10 Thread-8 : 7

    从程序运行结果可以看出,Thread-4和Thread-6执行结果都为2,明显发生了线程安全问题,当然,这种情况是偶然的。那么,出现这种问题的原因是什么呢?

    如果你对j = i++;底层是如果实现的,那么这个问题就好理解了。j = i++;底层实现为:

    int temp = i;
     i = i + 1;
     j = temp;

    那么很明显,Thread-4(或Thread-6)在执行改操作加1之前,Thread-6(或Thead-4)读到了相同的值。然后都进行加1操作,再打印出来。

    对于这类问题,我们可以使用原子变量来解决。在jdk1.5后,java.util.concurrent.atomic包中提供了常用的原子变量。原子变量有一下特性:

    • 底层代码使用volatile修饰,保证内存可见性
    • CAS(Compare-And-Swap)算法保证数据的原子性

    CAS算法

    CAS算法是硬件对于并发操作共享数据的支持,CAS包含了三个操作数:

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

    并且,当且仅当V==A时,V=B,否则,将不做任何操作。

    在了解了原子变量后,我们使用原子变量修改程序:

     1 class AtomicDemo implements Runnable {
     2 //    private int number = 0;
     3     private AtomicInteger number = new AtomicInteger();
     4 
     5     @Override
     6     public void run() {
     7         try {
     8             Thread.sleep(200);
     9         } catch (InterruptedException e) {
    10             e.printStackTrace();
    11         }
    12         System.out.println(Thread.currentThread().getName() + " : " + getNumber());
    13     }
    14     
    15     public int getNumber() {
    16 //        return number++;
    17         return number.getAndIncrement();
    18     }
    19 }
  • 相关阅读:
    去中心化共识
    创建你的第一个去中心化应用(dapp)
    务实的去中心化
    什么是去中心化市场(OpenBazaar)
    为什么要做去中心化市场(OpenBazaar)
    区块链让物联网真正实现去中心化
    去中心化市场OpenBazaar如何运转
    如何安装去中心化市场(OpenBazaar)
    android自定义View&自定义ViewGroup(上)
    android自定义View&自定义ViewGroup(上)
  • 原文地址:https://www.cnblogs.com/ccfdod/p/6392348.html
Copyright © 2020-2023  润新知