3

私は java.util.concurrent パッケージのコードを読んでいますが、クラス Unsafe (これらのシンクロナイザーを実装するために使用される) が興味深いと思います。クラス名自体がそれを思いとどまらせるように見えるため、実際のコードで使用することは決してないかもしれませんが、好奇心から、このクラスについて2つの質問があります。

1)。このクラスのシングルトン アクセサーは次のようになります。

    public static Unsafe getUnsafe() {
        Class cc = sun.reflect.Reflection.getCallerClass(2);
        if (cc.getClassLoader() != null)
            throw new SecurityException("Unsafe");
        return theUnsafe;
    }

したがって、このメソッドがユーザー コードから呼び出されると、例外がスローされます。これを回避するにはどうすればよいですか?(おそらく、ブートストラップクラスローダーによってロードされた独自のクラスを作成することによって可能ですか?これは可能ですか?)

2)。上記のコードはgetClassLoader、boostrap クラスローダーによってロードされたクラスに対して null を返すことを前提としています。しかし、の javadoc にClass#getClassLoaderは、「一部の実装では、ブートストラップ クラス ローダーを表すために null を使用する場合があります」と記載されています。これは、この前提に保証がないことを意味します。この仮定に違反する実装の場合、Unsafe (およびそれに依存する ReentrantLock などのさまざまなクラス) はまったく機能しませんか?

ありがとう!

4

2 に答える 2

4

これを回避するにはどうすればよいですか?

次のようにクラスにアクセスできます (セキュリティ マネージャーがアクセシビリティの変更を許可する場合)。

public static Unsafe getUnsafe() {
    try {
            Field f = Unsafe.class.getDeclaredField("theUnsafe");
            f.setAccessible(true);
            return (Unsafe)f.get(null);
    } catch (Exception e) { /* ... */ }
}

この仮定に違反する実装の場合、 Unsafe ... はまったく機能しませんか?

クラスの詳細Unsafeも実装固有です。Unsafeこれがクラスローダーサブシステムの他の実装と連携できると期待する理由はありません。

于 2012-05-31T07:41:15.690 に答える
0

Another way to go is to use jvm option -Xbootclasspath/a:<directories and zip/jar files separated by ;>

You can create a simple class which will call Unsafe.getUnsafe() and append it to bootclasspath.

public class UnsafeAccessor {

    public static Unsafe getUnsafe()  {
        return Unsafe.getUnsafe();
    }

}

Command line:

java -Xbootclasspath/a:&lt;path_to&gt;/unsafeaccessor.jar -cp

In such a way you will add this class directly to System Bootstrap Classloader. JVM will treat the class as part of JDK, and you can call UnsafeAccessor.getUnsafe() in your code instead of Unsafe.getUnsafe():

Unsafe unsafe = UnsafeAccessor.getUnsafe();
于 2012-07-14T14:57:17.987 に答える