zoukankan      html  css  js  c++  java
  • Java并发编程-原子操作的实现原理

    原子(atomic)本意时“不能被进一步分割的最小粒子”,而原子操作(atomic operation)意为“不可被中断的一个或一系列操作”。

    Java 如何实现原子操作

    在 Java 中可以通过锁和循环 CAS 的方式实现原子操作。

    1、使用循环 CAS 实现原子操作

    JVM 中的 CAS 操作正是利用了处理器提供的 CMPXCHG 指令实现的。自旋 CAS 实现的基本思路就是循环进行 CAS 操作直到成功为止,以下代码实现了一个基于 CAS 线程安全的计数器方法 safeCount 和一个非线程安全的计数器 count。

    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.atomic.AtomicInteger;
    
    /**
     * Author: YiFan
     * Date: 2018/11/25 20:39
     * Description: CAS操作
     */
    public class CASTest {
    
        private AtomicInteger atomicI = new AtomicInteger(0);
        private int i = 0;
    
        public static void main(String[] args) throws InterruptedException {
            final CASTest cas = new CASTest();
            List<Thread> threads = new ArrayList<>(600);
            long start = System.currentTimeMillis();
            for (int i = 0; i < 100; i++) {
                Thread t = new Thread(() -> {
                    for (int j = 0; j < 10000; j++) {
                        cas.count();
                        cas.safeCount();
                    }
                });
                threads.add(t);
            }
            for (Thread t:
                    threads
                 ) {
                t.start();
            }
            // 等待所有线程执行完成
            for (Thread t:
                    threads
                 ) {
                t.join();
            }
            System.out.println(cas.i);
            System.out.println(cas.atomicI.get());
            System.out.println(System.currentTimeMillis() - start);
        }
    
        // 非线程安全计数器
        private void count() {
            i++;
        }
    
        // 使用CAS实现线程安全计数器
        private void safeCount() {
            for (;;) {
                int i = atomicI.get();
                boolean suc = atomicI.compareAndSet(i, ++i);
                if (suc) {
                    break;
                }
            }
        }
    }
    

    该示例演示了多线程下对共享变量进行操作,count 方法中没有使用 CAS 操作,导致多个线程可以同时对共享变量 i 进行操作,所以导致最终的 i 值不为 100000。但是 safeCount 方法中使用了 CAS 操作,这样就解决的多线程下对 i++ 的原子性操作了,所以最终 i 值始终为 100000。

    2、使用锁机制实现原子操作

    锁机制保证了只有获得锁的线程才能够操作锁定的内存区域。JVM 内部实现了很多种锁机制,有偏向锁、轻量级锁和互斥锁。其中 JVM 实现锁的方式都用了循环 CAS,即当一个线程想进入同步块的时候使用循环 CAS 的方式来获取锁,当他退出同步块的时候使用循环 CAS 释放锁。

  • 相关阅读:
    MySQL约束条件
    MySQL基本数据类型
    MySQL基本sql语句,存储引擎,创建表的语法,严格模式
    MySQL环境变量配置及系统服务制作,设置及修改密码,跳过授权表并重置密码,统一编码
    数据库及SQL语句由来,重要概念介绍,MySQL安装,启动服务端及连接,初识SQL语句
    图书管理系统前端页面搭建
    Bootstrap组件2
    c#版工作流之流程发起(3)
    C#版工作流运行机制(1)
    c#版本工作流引擎状态机(2)
  • 原文地址:https://www.cnblogs.com/shanyingwufeng/p/10183953.html
Copyright © 2011-2022 走看看