JDKでの同時バグ?
3173 ワード
最近Javaの同時研究をして、何気なくJDK 8のSystem.コンソール()メソッドのソースコードには、次のコードが表示されます.
第一に、これは有名な二重検査のロックに似ているのではないでしょうか.もっとよく見ると、バグがあるようで、こう書くべきだったようです.
これこそ正しい二重検査ロックの正しい書き方です.
ではJDKの書き方に問題があるようです.
a,bの2つのスレッドがif(cons==null){に実行された後、aスレッドがロックに入り、1つのconsオブジェクトが得られ、ロックが出て、bスレッドがロックに入り、また異なるconsオブジェクトが得られた場合、注釈の中の:Returns the unique{@link java.io.console Console}object associated*with the current Java virtual machine,if any.
矛盾した.
またsun.misc.SharedSecrets.getJavaIOAccess().console();戻るたびに同じオブジェクトであるため、synchronized(System.class)ロックを使用する必要はありません.
しかし、JDKでこのような低級なバグが発生した場合、また不可能だと感じているのではないでしょうか.しかし、自分がコードから見ても確かにバグがあるので、その経緯を知っておいてください.
private static volatile Console cons = null;
/**
* Returns the unique {@link java.io.Console Console} object associated
* with the current Java virtual machine, if any.
*
* @return The system console, if any, otherwise <tt>null</tt>.
*
* @since 1.6
*/
public static Console console() {
if (cons == null) {
synchronized (System.class) {
cons = sun.misc.SharedSecrets.getJavaIOAccess().console();
}
}
return cons;
}
第一に、これは有名な二重検査のロックに似ているのではないでしょうか.もっとよく見ると、バグがあるようで、こう書くべきだったようです.
public static Console console() {
if (cons == null) {
synchronized (System.class) {
if (cons == null)
cons = sun.misc.SharedSecrets.getJavaIOAccess().console();
}
}
return cons;
}
これこそ正しい二重検査ロックの正しい書き方です.
ではJDKの書き方に問題があるようです.
a,bの2つのスレッドがif(cons==null){に実行された後、aスレッドがロックに入り、1つのconsオブジェクトが得られ、ロックが出て、bスレッドがロックに入り、また異なるconsオブジェクトが得られた場合、注釈の中の:Returns the unique{@link java.io.console Console}object associated*with the current Java virtual machine,if any.
矛盾した.
またsun.misc.SharedSecrets.getJavaIOAccess().console();戻るたびに同じオブジェクトであるため、synchronized(System.class)ロックを使用する必要はありません.
しかし、JDKでこのような低級なバグが発生した場合、また不可能だと感じているのではないでしょうか.しかし、自分がコードから見ても確かにバグがあるので、その経緯を知っておいてください.