JUC并发包下

1.原子整数

  * AtomicBoolean

  * AtomicInteger

  * AtomicLong

以AtomicInteger为例:

public class test {

    public static void main(String[] args) throws InterruptedException {
       AtomicInteger i = new AtomicInteger(0);

       //获取并自增(i= 0,结果i = 1,返回0),类似于i++
        System.out.println(i.getAndIncrement());

        //自增并获取(i = 1,结果 i =2;返回2);类似于 ++i
        System.out.println(i.incrementAndGet());

        //自减并获取(i=2,结果 i = 1,返回 1 ),类似于--i
        System.out.println(i.decrementAndGet());

        //获取并自减(i=1,结果 i = 0,返回 1 ),类似于i--
        System.out.println(i.getAndDecrement());

        //获取并加值(i=0,结果i=5,返回0),类似于 i += 5;
        System.out.println(i.getAndAdd(5));

        i.updateAndGet(new IntUnaryOperator() {
            @Override
            public int applyAsInt(int value) {
                value = value*10;
                return value;
            }
        });
    }

}

2.原子引用

* AtomicReference

* AtomicMarkableReference

* AtomicStampedReference

public class test {

    public static void main(String[] args) throws InterruptedException {
       DecimalAccount.demo(new DecimalAccountCas(new BigDecimal("10000")));
    }


}

class DecimalAccountCas implements DecimalAccount{

    private AtomicReference<BigDecimal> balance;  //范型中就是要保护的类型

    public DecimalAccountCas(BigDecimal balance) {
        this.balance = new AtomicReference<>(balance);
    }

    @Override
    public BigDecimal getBalance() {
        return balance.get();
    }

    @Override
    public void withdraw(BigDecimal amount) {
        while (true){
            BigDecimal pre = balance.get();
            BigDecimal next = pre.subtract(amount); //减去amount
            if (balance.compareAndSet(pre,next)){
                break;
            }
        }
    }
}

interface DecimalAccount{
    //获取余额
    BigDecimal getBalance();

    //取款
    void withdraw(BigDecimal amount);

    /*
    * 方法内会启动1000个线程,每个线程做 -10元操作,
    * 如果初始余额为10000 那么正确的结果为0
    * */
    static void demo(DecimalAccount account){
        ArrayList<Thread> ts = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            ts.add(new Thread(() -> {
                account.withdraw(BigDecimal.TEN);
            }));
        }
        ts.forEach(Thread :: start);
        ts.forEach(t -> {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        System.out.println(account.getBalance());
    }
}

AtomicStampedReference

AtomicReference会有一个问题(cas),cas会有ABA问题。

所以AtomicStampedReference就多了一个版本号来解决这个问题。

 

AtomicStampedReference可以给原子引用加上版本号,追踪原子引用整个的变化过程,如:A -> B -> A -> C,通过AtomicStampedReference,我们可以知道引用变量中途被更改了几次。

但是有时候,并不关心引用变量更改了几次,只是单纯的关心是否更改过,所以就有了AtomicMarkableReference

 AtomicMarkableReference

 3.原子数组

 

之前的原子引用保护的是多个线程对一个对象引用进行修改时的线程安全性。像之前的

ref这个保护的是BigDecimal,

 这里获取新的值,和变化以后的值。最后ref调用compeareAndSet变化的引用本身,变化成功就是next那个引用。

但是有时候我们有时候并不是想修改引用本身而是想修改对象里面的内容,例如:数组(要对数组里面的元素保证线程安全)

*  AtomicIntegerArray(保护的数组里面元素是整型的)

 AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(10);

* AtomicLongArray(保护的数组里面元素是长整型的)

* AtomicReferenceArray(保护的数组里面元素是引用类型的)

4.原子字段更新器

* AtomicReferenceFieldUpdater  //保护的是对象里面某个引用类型的字段

* AtomicIntegerFieldUpdater

* AtomicLongFieldUpdater

 

5.原子累加器 

AtomicInteger做累加的效率没有AtomicAdder的高。

 即AtomicInteger对一个变量累加,而AtomicAdder是对多个变量累加。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值