atomic基本類型
常見方法
public final int get()
public final int getAndSet(int newValue)
public final int incrementAndGet()
public final int decrementAndGet()
public final int addAndGet(int delta)//獲取當前的值並加上預期的值
//如果當前的值和期待值expect相同,則把當前值設置爲update
public final boolean compareAndSet(int expect, int update)
atomic*FieldUpdater
代碼示例
package atomic;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
/**
* 描述: 演示AtomicIntegerFieldUpdater的用法
*/
public class AtomicIntegerFieldUpdaterDemo implements Runnable{
static Candidate tom;
static Candidate peter;
public static AtomicIntegerFieldUpdater<Candidate> scoreUpdater = AtomicIntegerFieldUpdater
.newUpdater(Candidate.class, "score");
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
peter.score++;
scoreUpdater.getAndIncrement(tom);
}
}
public static class Candidate {
volatile int score;
}
public static void main(String[] args) throws InterruptedException {
tom=new Candidate();
peter=new Candidate();
AtomicIntegerFieldUpdaterDemo r = new AtomicIntegerFieldUpdaterDemo();
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("普通變量:"+peter.score);
System.out.println("升級後的結果"+ tom.score);
}
}
adder累加器
package atomic;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
/**
* 描述: 演示高併發場景下,LongAdder比AtomicLong性能好
*/
public class LongAdderDemo {
public static void main(String[] args) throws InterruptedException {
LongAdder counter = new LongAdder();
ExecutorService service = Executors.newFixedThreadPool(20);
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
service.submit(new Task(counter));
}
service.shutdown();
while (!service.isTerminated()) {
}
long end = System.currentTimeMillis();
System.out.println(counter.sum());
System.out.println("LongAdder耗時:" + (end - start));
}
private static class Task implements Runnable {
private LongAdder counter;
public Task(LongAdder counter) {
this.counter = counter;
}
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
counter.increment();
}
}
}
}
爲什麼LongAdder比較快?
因爲AtomicLong需要flush和refresh.讓不同的線程中看見主內存的最新值。
而Adder每個線程只在自己線程中操作。