像许多性能问题一样,真正的问题是简单性和清晰性。我建议使用 synchronized 或 volatile ,因为两者都使用可能会造成混淆。两者都使用是多余的,因此效率略低,但不太重要。我会更担心使代码尽可能易于理解,并且不要做任何你需要做的事情。
在您的第一种情况下,只有 volatile 才有意义(或一致地使用同步)
class A {
private volatile int a;
public int getA() {...}
public void setA(int a) {...}
}
在第二种情况下,在本地对象上同步是没有意义的,您可以将其删除。我也不会扩展 Thread,这是不好的做法。
虽然您可能有 1000 个线程,但您可能只有 8-16 个 CPU 有这么多 CPU 绑定线程是个坏主意。减少线程数,您可能会通过减少开销来提高性能。
您应该将它们设计为尽可能独立,因为如果您不能这样做,单个线程可能会更快,因为它不会有缓存一致性。
恕我直言,使用枚举比使用 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