我測試了多線程Atomic Integer與比較同步方法的速度有多快,但是我得到的結果是Atomic Integer比synchronized方法慢。AtomicInteger比同步更慢
我讀了Java API Reference,我明白Atomic Integer在多線程中比同步更快。
所以我想知道爲什麼我用原子整數得到不好的結果的原因。 我的測試代碼錯了?
這裏是我的代碼
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicThreadTest {
// Number of thread to run
private static final int THREAD_NUM = 1000;
// Repetition number to count up
private static final int ROOP_NUM = 200000;
// Base counter class
private abstract class Counter implements Runnable {
@Override
public void run() {
for (int i = 0; i < ROOP_NUM; i++) {
increment();
}
}
// Increment method
public abstract void increment();
// Get result of calculation
public abstract int getResult();
// Get name of the class
@Override
public String toString() {
return getClass().getSimpleName();
}
}
// Use no thread safe
private static int count = 0;
private class NoThreadSafeCounter extends Counter {
@Override
public void increment() {
count++;
}
@Override
public int getResult() {
return count;
}
}
// Use volatile
private static volatile int volatileCount = 0;
private class VolatileCounter extends Counter {
@Override
public void increment() {
volatileCount++;
}
@Override
public int getResult() {
return volatileCount;
}
}
// Use synchronized
private static int synchronizedCount = 0;
private class SynchronizedCounter extends Counter {
@Override
public synchronized void increment() {
synchronizedCount++;
}
@Override
public int getResult() {
return synchronizedCount;
}
}
// Use AtomicInteger
private static AtomicInteger atomicCount = new AtomicInteger(0);
private class AtomicCounter extends Counter {
@Override
public void increment() {
atomicCount.incrementAndGet();
}
@Override
public int getResult() {
return atomicCount.get();
}
}
public static void main(String[] args) {
AtomicThreadTest testClass = new AtomicThreadTest();
Counter[] testCounter = {
testClass.new NoThreadSafeCounter(),
testClass.new VolatileCounter(),
testClass.new SynchronizedCounter(),
testClass.new AtomicCounter(),
};
for (Counter c : testCounter) {
System.out.println("-------------------------");
System.out.printf("Test for class : %s\n", c.toString());
try {
test(c);
} catch (InterruptedException e) {
System.out.println("Test halted");
} finally {
System.out.println("");
System.gc();
}
}
System.out.println("-------------------------");
}
public static void test(final Counter counter) throws InterruptedException {
System.out.printf("Start with threads : %d, roop : %d\n", THREAD_NUM, ROOP_NUM);
final long startTime = System.currentTimeMillis();
// Create THREAD_NUM threads and run them
Thread[] threads = new Thread[THREAD_NUM];
for (int i = 0; i < THREAD_NUM; i++) {
threads[i] = new Thread(counter);
threads[i].start();
}
// Wait for all threads other than this end
while (Thread.activeCount() > 1) {
Thread.sleep(10);
}
final long endTime = System.currentTimeMillis();
System.out.printf("Result %d, Expected %d\n", counter.getResult(), THREAD_NUM*ROOP_NUM);
System.out.printf("Time to calc : %d\n", endTime-startTime);
}
}
而且我得到了下面的結果。
-------------------------
Test for class : NoThreadSafeCounter
Start with threads : 1000, roop : 200000
Result 198785583, Expected 200000000
Time to calc : 127
-------------------------
Test for class : VolatileCounter
Start with threads : 1000, roop : 200000
Result 19162116, Expected 200000000
Time to calc : 4458
-------------------------
Test for class : SynchronizedCounter
Start with threads : 1000, roop : 200000
Result 200000000, Expected 200000000
Time to calc : 8426
-------------------------
Test for class : AtomicCounter
Start with threads : 1000, roop : 200000
Result 200000000, Expected 200000000
Time to calc : 15190
您不應該調用'System.gc()',因爲您不知道它何時會被執行。你沒有使用大量的內存,在執行期間你不太可能需要GC – Dici
順便說一下,你的同步(最後的while循環)很糟糕,並且消耗了大量的CPU。你應該使用類似信號量的東西 – Dici
@Dici謝謝你的回覆。對於system.gc(),我再次讀取我的代碼並瞭解每個Counter對象非常簡單,並且消耗的內存很少。所以,我不需要調用'System.gc()'。這樣對嗎? – user2738844