【参考】volatile 解决多线程内存不可见问题。对于一写多读,是可以解决变量同步问题,但是如果多写,同样无法解决线程安全问题。 说明:如果是 count++操作,使用如下类实现:AtomicInteger count = new AtomicInteger(); count.addAndGet(1); 如果是 JDK8,推荐使用 LongAdder 对象,比 AtomicLong 性能更好(减少乐观锁的重试次数)。
class Resource {
int count;
public synchronized void incrementBySynchronized() {
count++;
}
AtomicLong atomicLong = new AtomicLong();
public void incrementByAtomicLong() {
atomicLong.incrementAndGet();
}
LongAdder longAdder = new LongAdder();
public void incrementByLongAdder() {
longAdder.increment();
}
LongAccumulator longAccumulator = new LongAccumulator((x, y) -> x + y, 0);
public void incrementByLongAccumulator() {
longAccumulator.accumulate(1);
}
}
public static void main(String[] args) throws InterruptedException {
int threadCount = 50;
int _1W = 10000;
Resource resource = new Resource();
CountDownLatch countDownLatch1 = new CountDownLatch(threadCount);
CountDownLatch countDownLatch2 = new CountDownLatch(threadCount);
CountDownLatch countDownLatch3 = new CountDownLatch(threadCount);
CountDownLatch countDownLatch4 = new CountDownLatch(threadCount);
long startTime, endTime;
startTime = System.currentTimeMillis();
for (int i = 0; i < threadCount; i++) {
new Thread(() -> {
for (int j = 0; j < 100 * _1W; j++) {
resource.incrementBySynchronized();
}
countDownLatch1.countDown();
}).start();
}
countDownLatch1.await();
endTime = System.currentTimeMillis();
System.out.println("incrementBySynchronized " + resource.count + " 耗时 " + (endTime - startTime));
startTime = System.currentTimeMillis();
for (int i = 0; i < threadCount; i++) {
new Thread(() -> {
for (int j = 0; j < 100 * _1W; j++) {
resource.incrementByAtomicLong();
}
countDownLatch2.countDown();
}).start();
}
countDownLatch2.await();
endTime = System.currentTimeMillis();
System.out.println("incrementByAtomicLong " + resource.atomicLong.get() + " 耗时 " + (endTime - startTime));
startTime = System.currentTimeMillis();
for (int i = 0; i < threadCount; i++) {
new Thread(() -> {
for (int j = 0; j < 100 * _1W; j++) {
resource.incrementByLongAdder();
}
countDownLatch3.countDown();
}).start();
}
countDownLatch3.await();
endTime = System.currentTimeMillis();
System.out.println("incrementByLongAdder " + resource.longAdder.sum() + " 耗时 " + (endTime - startTime));
startTime = System.currentTimeMillis();
for (int i = 0; i < threadCount; i++) {
new Thread(() -> {
for (int j = 0; j < 100 * _1W; j++) {
resource.incrementByLongAccumulator();
}
countDownLatch4.countDown();
}).start();
}
countDownLatch4.await();
endTime = System.currentTimeMillis();
System.out.println("incrementByLongAccumulator " + resource.longAccumulator.get() + " 耗时 " + (endTime - startTime));
}
incrementBySynchronized 50000000 耗时 1301
incrementByAtomicLong 50000000 耗时 1011
incrementByLongAdder 50000000 耗时 74
incrementByLongAccumulator 50000000 耗时 82