【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);
}
}