多くのパフォーマンスに関する質問と同様に、真の問題は単純さと明快さです。両方を使用すると混乱する可能性があるため、synchronized または volatile を使用することをお勧めします。両方を使用することは冗長であるため、わずかに非効率的ですが、問題になるほどではありません。コードをできるだけ理解しやすくすることについてもっと心配し、必要以上のことはしません。
最初のケースでは、volatile のみが意味をなします (または、synchronized を一貫して使用する)
class A {
private volatile int a;
public int getA() {...}
public void setA(int a) {...}
}
2 番目のケースでは、ローカル オブジェクトで同期しても意味がありません。削除できます。私も Thread を拡張しません。これは悪い習慣です。
1000 のスレッドがあるかもしれませんが、8 ~ 16 個の CPU しかない可能性があります。これほど多くの CPU バウンド スレッドを使用することはお勧めできません。スレッドの数を減らすと、オーバーヘッドが減り、パフォーマンスが向上する可能性があります。
それらが可能な限り独立するように設計する必要があります。それができない場合、キャッシュの一貫性がオーバーヘッドにならないため、単一のスレッドの方が高速になる可能性があります。
IMHO列挙型の使用は、Guava MemorizeSupplierを使用するよりも簡単ですが、どちらが高速ですか
public class GuavaMain {
interface AAA {
int hashCode();
}
enum Singleton implements AAA {
INSTANCE
}
public static void main(String... ignored) {
Supplier<AAA> memoize = Suppliers.memoize(new Supplier<AAA>() {
@Override
public AAA get() {
return new AAA() {
};
}
});
for (int j = 0; j < 10; j++) {
int runs = 5000;
long time1 = System.nanoTime();
for (int i = 0; i < runs; i++) {
// call a method on out lazy instance
Singleton.INSTANCE.hashCode();
}
long time2 = System.nanoTime();
for (int i = 0; i < runs; i++) {
// call a method on out lazy instance
memoize.get().hashCode();
}
long time3 = System.nanoTime();
System.out.printf("enum took %,d ns and memorize took %,d ns avg%n",
(time2 - time1) / runs, (time3 - time2) / runs);
}
}
}
版画
enum took 179 ns and memorize took 301 ns avg
enum took 74 ns and memorize took 97 ns avg
enum took 62 ns and memorize took 175 ns avg
enum took 58 ns and memorize took 146 ns avg
enum took 58 ns and memorize took 147 ns avg
enum took 56 ns and memorize took 111 ns avg
enum took 36 ns and memorize took 86 ns avg
enum took 36 ns and memorize took 84 ns avg
enum took 36 ns and memorize took 82 ns avg
enum took 36 ns and memorize took 82 ns avg