Вы спрашиваете, почему есть два способа сделать одно и то же?
Когда метод рыночный как синхронизированный, было бы излишним иметь также инструкции мониторинга / выхода.Если бы он имел только команду monitorenter / exit, вы бы не поспорили внешне увидеть, что метод синхронизирован (без чтения реального кода)
Существует более нескольких примеров двух или более способов сделать то же самоевещь.У каждого есть свои сильные и слабые стороны.(например, многие однобайтовые инструкции являются короткими версиями двухбайтовой инструкции)
РЕДАКТИРОВАТЬ: Я должен что-то упустить в вопросе, потому что вызывающему не нужно знать, синхронизирован ли вызываемый
public static void main(String... args) {
print();
printSynchronized();
printSynchronizedInternally();
}
public static void print() {
System.out.println("not synchronized");
}
public static synchronized void printSynchronized() {
System.out.println("synchronized");
}
public static void printSynchronizedInternally() {
synchronized(Class.class) {
System.out.println("synchronized internally");
}
}
производит код
public static void main(java.lang.String[]);
Code:
0: invokestatic #2; //Method print:()V
3: invokestatic #3; //Method printSynchronized:()V
6: invokestatic #4; //Method printSynchronizedInternally:()V
9: return
public static void print();
Code:
0: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #6; //String not synchronized
5: invokevirtual #7; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
public static synchronized void printSynchronized();
Code:
0: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #8; //String synchronized
5: invokevirtual #7; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
public static void printSynchronizedInternally();
Code:
0: ldc_w #9; //class java/lang/Class
3: dup
4: astore_0
5: monitorenter
6: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream;
9: ldc #10; //String synchronized internally
11: invokevirtual #7; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
14: aload_0
15: monitorexit
16: goto 24
19: astore_1
20: aload_0
21: monitorexit
22: aload_1
23: athrow
24: return
Exception table:
from to target type
6 16 19 any
19 22 19 any
}