前言
10w个用户,对某个按钮点50次
四种方式
public class ClickDemo {
public static final int SIZE = 100000;
public static final int THREAD_NUMBER = 50;
public static void main(String[] args) throws Exception {
clickBySynchronized();
clickByAtomicLong();
clickByLongAdder();
clickByLongAccumulator();
}
public static void clickBySynchronized() throws Exception {
ClickNumber clickNumber = new ClickNumber();
CountDownLatch countDownLatch = new CountDownLatch(THREAD_NUMBER);
long startTime = System.currentTimeMillis();
for (int i = 0; i < THREAD_NUMBER; i++) {
new Thread(() -> {
try {
for (int j = 0; j < SIZE; j++) {
clickNumber.clickBySynchronized();
}
} finally {
countDownLatch.countDown();
}
}, String.valueOf(i)).start();
}
countDownLatch.await();
long endTime = System.currentTimeMillis();
System.out.println("clickBySynchronized cost:" + (endTime - startTime) + "ms" + "\t" + clickNumber.number);
}
public static void clickByAtomicLong() throws Exception {
ClickNumber clickNumber = new ClickNumber();
CountDownLatch countDownLatch = new CountDownLatch(THREAD_NUMBER);
long startTime = System.currentTimeMillis();
for (int i = 0; i < THREAD_NUMBER; i++) {
new Thread(() -> {
try {
for (int j = 0; j < SIZE; j++) {
clickNumber.clickByAtomicLong();
}
} finally {
countDownLatch.countDown();
}
}, String.valueOf(i)).start();
}
countDownLatch.await();
long endTime = System.currentTimeMillis();
System.out.println("clickByAtomicLong cost:" + (endTime - startTime) + "ms" + "\t" + clickNumber.atomicLong.get());
}
public static void clickByLongAdder() throws Exception {
ClickNumber clickNumber = new ClickNumber();
CountDownLatch countDownLatch = new CountDownLatch(THREAD_NUMBER);
long startTime = System.currentTimeMillis();
for (int i = 0; i < THREAD_NUMBER; i++) {
new Thread(() -> {
try {
for (int j = 0; j < SIZE; j++) {
clickNumber.clickByLongAdder();
}
} finally {
countDownLatch.countDown();
}
}, String.valueOf(i)).start();
}
countDownLatch.await();
long endTime = System.currentTimeMillis();
System.out.println("clickByLongAdder cost:" + (endTime - startTime) + "ms" + "\t" + clickNumber.longAdder.sum());
}
public static void clickByLongAccumulator() throws Exception {
ClickNumber clickNumber = new ClickNumber();
CountDownLatch countDownLatch = new CountDownLatch(THREAD_NUMBER);
long startTime = System.currentTimeMillis();
for (int i = 0; i < THREAD_NUMBER; i++) {
new Thread(() -> {
try {
for (int j = 0; j < SIZE; j++) {
clickNumber.clickByLongAccumulator();
}
} finally {
countDownLatch.countDown();
}
}, String.valueOf(i)).start();
}
countDownLatch.await();
long endTime = System.currentTimeMillis();
System.out.println("clickByLongAccumulator cost:" + (endTime - startTime) + "ms" + "\t" + clickNumber.longAccumulator.get());
}
}
class ClickNumber {
int number = 0;
public synchronized void clickBySynchronized() {
number++;
}
AtomicLong atomicLong = new AtomicLong(0);
public void clickByAtomicLong() {
atomicLong.getAndIncrement();
}
LongAdder longAdder = new LongAdder();
public void clickByLongAdder() {
longAdder.increment();
}
LongAccumulator longAccumulator = new LongAccumulator((x, y) -> x + y, 0);
public void clickByLongAccumulator() {
longAccumulator.accumulate(1);
}
}
可以看出,高并发的情况下,LongAdder 的性能比 AtomicLong 高很多