5

私は現在サンプル演習を行っていますが、AutomicInteger を揮発性プログラムに置き換えると、プログラムがより速く実行されるという奇妙な観察結果が 1 つ見つかりました。注:読み取り操作のみを行っています。

コード:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class Main {

AtomicInteger integer  = new AtomicInteger(100000000);
// volatile int integer= 100000000;

public static void main(String[] args) {
// We will store the threads so that we can check if they are done
List<Thread> threads = new ArrayList<Thread>();
 long start = System.currentTimeMillis();
 Main main = new Main();
// We will create 500 threads

for (int i = 0; i < 500; i++) {
  Runnable task = new MyRunnable(main.integer);
  Thread worker = new Thread(task);
  // We can set the name of the thread
  worker.setName(String.valueOf(i));
  // Start the thread, never call method run() direct
  worker.start();
  // Remember the thread for later usage
  threads.add(worker);
}
int running = 0;
do {
  running = 0;
  for (Thread thread : threads) {
    if (thread.isAlive()) {
      running++;
    }
  }
  System.out.println("We have " + running + " running threads. ");
} while (running > 0);

System.out.println("Total Time Required :" +(System.currentTimeMillis()- start));
}
} 

MyRunnable クラス:

 import java.util.concurrent.atomic.AtomicInteger;

public class MyRunnable implements Runnable {
private final AtomicInteger countUntil;

MyRunnable(AtomicInteger countUntil) {
    this.countUntil = countUntil;
}

@Override
public void run() {
    long sum = 0;
    for (long i = 1; i < countUntil.intValue(); i++) {
        sum += i;
    }
    System.out.println(sum);
}
}

私のマシンで AutomicInteger を使用してこのプログラムを実行するのに必要な時間。

合計所要時間:102169

総所要時間:90375

私のマシンで揮発性を使用してこのプログラムを実行するのに必要な時間

合計所要時間:66760

総所要時間:71773

これは、読み取り操作でも volatile が AutomicInteger よりも高速であることを意味しますか?

4

4 に答える 4

6

AtomicInteger読み取りコンテキストでは、基本的に薄いラッパーvolatile intです:

private volatile int value;

public final int get() {
    return value;
}

public int intValue() {
    return get();
}

ラップされた値を単独で取得した場合よりもラッパーが高速になるとは思わないでください。インライン化が JVM によって採用されている場合と同じくらい高速になります。volatile int


ヒント: 「読み取り操作のみを行っている」場合、これはさらに高速になります。

static final int integer= 100000000;
于 2012-08-18T12:42:05.727 に答える
1

volatile int は AtomicInteger よりも高速です

The Java™ Language Specification のセクション 17.4に記載されているように、アトミックのアクセスと更新のメモリ効果は、通常、volatile の規則に従います。以下は、Atomic 型と比較した volatile int の欠点です。

  • get には、揮発性変数を読み取るというメモリ効果があります。

  • set には、揮発性変数を書き込む (割り当てる) というメモリ効果があります。

  • lazySet には、揮発性変数を書き込む (割り当てる) というメモリ効果がありますが、それ自体は通常の不揮発性書き込みで並べ替えの制約を課さない後続の (前ではなく) メモリ アクションで並べ替えを許可する点が異なります。他の使用コンテキストの中でも、lazySet は、ガベージ コレクションのために、二度とアクセスされない参照を null にするときに適用される場合があります。

  • weakCompareAndSet は、変数をアトミックに読み取り、条件付きで書き込みますが、事前発生順序付けを作成しません。そのため、weakCompareAndSet のターゲット以外の変数の前後の読み取りおよび書き込みに関して保証はありません。

  • compareAndSet および getAndIncrement などの他のすべての読み取りおよび更新操作には、揮発性変数の読み取りと書き込みの両方のメモリ効果があります。

于 2013-11-19T05:33:32.847 に答える
1

この質問は、特定の JVM、ハードウェア、およびオペレーティング システムに依存するため、考えられる唯一の答えは「おそらく」です。

于 2012-08-18T12:41:16.600 に答える
0

volatile int は AtomicInteger よりも高速である可能性がありますが、これが目立つアプリケーションはほとんどないはずです。それでも、AtomicInteger はより幅広い潜在的な用途を提供します。

于 2012-08-18T12:42:33.200 に答える