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" + "---抢夺失败,已被其他线程占用");
            }
        }
    }
  • 相关阅读:
    java 23种设计模式及具体例子 收藏有时间慢慢看
    java中的内存一般分成几部分?
    深入浅出Java垃圾回收机制
    HashMap、HashTable、LinkedHashMap和TreeMap用法和区别
    java 序列化与反序列化
    JAVA中int、String的类型相互转换
    java IO和NIO 的区别
    数据库设计
    服务器硬件优化
    系统配置优化
  • 原文地址:https://www.cnblogs.com/shiblog/p/15749229.html
Copyright © 2011-2022 走看看