zoukankan      html  css  js  c++  java
  • 十一、原子更新器

    使用目的

    以一种线程安全的方式操作非线程安全对象内的某些字段。

    优点

    不用对对象加锁,只针对对象的某个属性进行原子类操作,提高并发性。

    使用方式

    1、更新的对象属性必须使用public volatile修饰符。

    2、因为对象的属性修改类型原子类都是抽象类,所以每次使用都必须使用静态方法newUpdater()创建一个更新器,并且需要设置想要更新的类和属性。

    AtomicIntegerFieldUpdater

    public class AtomicIntegerFieldUpdaterDemo {
    
        public static void main(String[] args) throws InterruptedException {
            BankAccout bankAccout = new BankAccout();
            //  线程数量
            int count = 1000;
            //  CountDownLatch
            final CountDownLatch latch = new CountDownLatch(count);
    
            for (int i = 1; i <= count; i++) {
                new Thread(() -> {
                    try {
                        bankAccout.transfer(bankAccout);
                    } finally {
                        latch.countDown();
                    }
                }, String.valueOf(i)).start();
    
            }
            latch.await();
    
            System.out.println(Thread.currentThread().getName() + "\t" + "------bankAccount:" + bankAccout.money);
        }
    }
    
    class BankAccout {
        String bankName = "ccb";
    
        public volatile int money = 0;
    
        AtomicIntegerFieldUpdater FieldUpdater = AtomicIntegerFieldUpdater.newUpdater(BankAccout.class, "money");
    
        public void transfer(BankAccout bankAccout) {
            FieldUpdater.incrementAndGet(bankAccout);
        }
    }

    AtomicReferenceFieldUpdater

    public class AtomicReferenceFieldUpdaterDemo {
        public static void main(String[] args) {
            MyVar myVar = new MyVar();
    
            for (int i = 1; i <= 5; i++) {
                new Thread(() -> {
                    myVar.init(myVar);
                }, String.valueOf(i)).start();
            }
        }
    }
    
    class MyVar {
        public volatile Boolean isInit = Boolean.FALSE;
        AtomicReferenceFieldUpdater<MyVar, Boolean> FieldUpdater = AtomicReferenceFieldUpdater.newUpdater(MyVar.class, Boolean.class, "isInit");
    
        public void init(MyVar myVar) {
            if (FieldUpdater.compareAndSet(myVar, Boolean.FALSE, Boolean.TRUE)) {
                System.out.println(Thread.currentThread().getName() + "\t" + "---start init");
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "\t" + "---end init");
            } else {
                System.out.println(Thread.currentThread().getName() + "\t" + "---抢夺失败,已被其他线程占用");
            }
        }
    }
  • 相关阅读:
    Typescript 最佳实践
    《三》大话 Typescript 接口
    二. 细说小程序登陆
    一. 优化小程序自身的Storage
    开始你的第一个npm脚本工具
    javascript 玩转Date对象
    createjs 小游戏开发实战
    前端实现连连看小游戏(1)
    一篇文章带你快速入门createjs
    从0到1完成小程序开发(4)
  • 原文地址:https://www.cnblogs.com/shiblog/p/15749229.html
Copyright © 2011-2022 走看看