当前位置: 首页 > article >正文

【JUC】13-原子类

1. CountDownLatch实现线程等待

 CountDownLatch实现线程等待。

    public static void main(String[] args) {
        AtomicInteger num = new AtomicInteger(1);
        int SIZE = 50;
        CountDownLatch countDownLatch = new CountDownLatch(SIZE);
        for(int i = 0; i<SIZE; i++) {
            new Thread(()->{
                try {
                    for(int j=0; j<1000; j++) {
                        num.getAndIncrement();
                    }
                } finally {
                    countDownLatch.countDown();
                }
            }).start();
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(num.get());
    }

2. AtomicMarkableReference

 AtomicMarkableReference流水号为Boolean类型,只能改为true和false。

/**
 * CAS----Unsafe----do while+ABA----AtomicStampedReference,AtomicMarkableReference
 */
    static AtomicMarkableReference<Integer> atomicMarkableReference = new AtomicMarkableReference<>(100, false);
    public static void main(String[] args) {
        new Thread(()->{
            boolean marked = atomicMarkableReference.isMarked();
            Integer reference = atomicMarkableReference.getReference();
            atomicMarkableReference.compareAndSet(reference, 200, marked, !marked);
        }).start();
        new Thread(()->{
            boolean marked = atomicMarkableReference.isMarked();
            Integer reference = atomicMarkableReference.getReference();
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            atomicMarkableReference.compareAndSet(reference, 300, marked, !marked);
            System.out.println("t2 " + atomicMarkableReference.isMarked() + " " + atomicMarkableReference.getReference());
        }).start();
    }

3. AtomicIntegerUpdater

 AtomicIntegerUpdater用于实现数据的原子性,但程序运行速度下降会很少。可以对对象的某一属性进行加锁,而不需要锁整个对象,但对象的这个属性需要被volatile修饰。

class BankAccount {
    // AtomicIntegerFieldUpdater 修饰的属性必须被volatile所修饰
    public volatile int money = 0;
    public synchronized void add(int cnt) {
        money = money + cnt;
    }
    AtomicIntegerFieldUpdater<BankAccount> updater = AtomicIntegerFieldUpdater.newUpdater(BankAccount.class, "money");
    public void saveMoney() {
        updater.getAndIncrement(this);
    }
}

public class NoSyncAdd {
    public static void main(String[] args) {
        BankAccount account = new BankAccount();
        CountDownLatch count = new CountDownLatch(10);
        for(int i=0; i<10; i++) {
            new Thread(()->{
                for (int j = 0; j < 500; j++) {
                    account.saveMoney();
                }
                count.countDown();
            }).start();
        }
        try {
            count.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(account.money);
    }
}

4. AtomicReferenceFieldUpdater

 AtomicReferenceFieldUpdater可以用于更多的类型。

class Manager {
    public volatile Boolean isInit = false;
    AtomicReferenceFieldUpdater<Manager, Boolean> updater = AtomicReferenceFieldUpdater.newUpdater(Manager.class, Boolean.class,"isInit");
    public void init(Manager manager) {
        if (updater.compareAndSet(manager, Boolean.FALSE, Boolean.TRUE)) {
            System.out.println(Thread.currentThread().getName() + "start");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(Thread.currentThread().getName() + "初始化完成");
        } else {
            System.out.println(Thread.currentThread().getName() + "complete");
        }
    }
}
public class ObjectSyncInit {
    public static void main(String[] args) {
        Manager manager = new Manager();
        for(int i=0; i<10; i++) {
            new Thread(()->{
                manager.init(manager);
            }).start();
        }
    }
}

5. LongAddr和LongAccumulator实现高效的自增操作

 LongAddr和LongAccumulator实现高效的自增操作。

package com.juc.demo.Atomic;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAccumulator;
import java.util.concurrent.atomic.LongAdder;

class Praise {
    public int count = 0;
    public synchronized void syncAdd() {
        count ++;
    }

    public AtomicLong atomicLong = new AtomicLong(0);

    public void atomicAdd() {
        atomicLong.getAndIncrement();
    }

    public LongAdder longAdder = new LongAdder();
    public void adderAdd() {
        longAdder.increment();
    }

    public LongAccumulator accumulatorLong = new LongAccumulator((x,y)->{
        return x + y;
    },0);

    public void accumulator() {
        accumulatorLong.accumulate(1);
    }
}

public class SyncAdd {
    public static void main(String[] args) {
        Praise praise = new Praise();
        long start = System.currentTimeMillis();
        CountDownLatch countDownLatch = new CountDownLatch(50);
        for(int i=0; i<50; i++) {
            new Thread(()->{
                for (int j = 0; j < 10000000; j++) {
                    // 36949ms
                    // praise.syncAdd();

                    // 6997ms
                    // praise.atomicAdd();

                    // 327ms
                    // praise.adderAdd();

                    // 348ms
                    praise.accumulator();
                }
                countDownLatch.countDown();
            }).start();

        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        long end = System.currentTimeMillis();
        System.out.println(praise.accumulatorLong);
        System.out.println(end - start);
    }
}


http://www.kler.cn/a/297034.html

相关文章:

  • 如何在算家云搭建MindSearch(智能搜索)
  • [N1CTF 2018]eating_cms1
  • 【Redis】redis5种数据类型(string)
  • blender云渲染来了,blender云渲染教程!
  • CTFHub技能树-Git泄漏-Log
  • 5.测试用例设计方法
  • 移动端测试
  • 转义字符笔记
  • 代理模式详解
  • Treeview创始人谈空间计算/XR在培训和教育的应用场景
  • 13、Flink SQL 的 时间属性 介绍
  • 【Qt】Qt与Html网页进行数据交互
  • MySQL基本知识2
  • 鸿蒙开发Tabs栏Scroll的使用 【第四篇】
  • Linux 之 mysql-5.7.44 下载/安装(离线)
  • AI 浪潮中的一体化数据库|外滩大会之OceanBase实录
  • 【OpenWrt(3)】内网搭建iperf3测速服务器
  • 如何搭建ETL?
  • 【数据结构】排序算法篇二
  • 【吊打面试官系列-Redis面试题】怎么理解 Redis 事务?