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" + "---抢夺失败,已被其他线程占用");
            }
        }
    }
  • 相关阅读:
    Treap 树堆 容易实现的平衡树
    (转)Maven实战(二)构建简单Maven项目
    (转)Maven实战(一)安装与配置
    根据请求头跳转判断Android&iOS
    (转)苹果消息推送服务器 php 证书生成
    (转)How to renew your Apple Push Notification Push SSL Certificate
    (转)How to build an Apple Push Notification provider server (tutorial)
    (转)pem, cer, p12 and the pains of iOS Push Notifications encryption
    (转)Apple Push Notification Services in iOS 6 Tutorial: Part 2/2
    (转)Apple Push Notification Services in iOS 6 Tutorial: Part 1/2
  • 原文地址:https://www.cnblogs.com/shiblog/p/15749229.html
Copyright © 2011-2022 走看看