之前在网上看到一个面试题目:synchronzied 最好的锁对象是什么
当时第一反应是 new Object,但是后来看到这篇文章:Object vs byte[0] as lock
大意就是 new byte[0]作为锁对象会更好,能够减少字节码操作的次数
下面来验证一下
1 2 3 4 5 6 7
| public class ObjectSynchronizedDemo { private final Object obj = new Object(); }
public class ArraySynchronizedDemo { private final byte[] lockObj = new byte[0]; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| ObjectSynchronizedDemo.class { public com.aias.learn.test.ObjectSynchronizedDemo(); descriptor: ()V flags: ACC_PUBLIC Code: stack=3, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: aload_0 5: new #2 // class java/lang/Object 8: dup 9: invokespecial #1 // Method java/lang/Object."<init>":()V 12: putfield #3 // Field obj:Ljava/lang/Object; 15: return LineNumberTable: line 7: 0 line 8: 4 LocalVariableTable: Start Length Slot Name Signature 0 16 0 this Lcom/aias/learn/test/ObjectSynchronizedDemo; }
ArraySynchronizedDemo.class { public com.aias.learn.test.ArraySynchronizedDemo(); descriptor: ()V flags: ACC_PUBLIC Code: stack=2, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: aload_0 5: iconst_0 6: newarray byte 8: putfield #2 // Field lockObj:[B 11: return LineNumberTable: line 7: 0 line 8: 4 LocalVariableTable: Start Length Slot Name Signature 0 12 0 this Lcom/aias/learn/test/ArraySynchronizedDemo; }
|
可以看出,new byte[0]确实比 new Object() 少 4 条字节码操作。
再计算一下内存占用情况:
new Object()内存占用:
Mark Word(8 字节)+klass pointer(开启指针压缩,4 字节)+对齐填充(4 字节) = 16 字节
new byte[0]内存占用:
Mark Word(8 字节)+klass pointer(开启指针压缩,4 字节)+数组长度(int,4 字节) = 16 字节
所以两种锁对象占用内存是相等的。