1

この問題について検索してみましたが、それを試したのは私だけであるかのように何も見つかりませんでした。

基本的に、含まれているクラスのコンストラクター内でリソースアクセスを同期するために使用する静的オブジェクトがあり、時々それが機能しないことに気付きました!

private static Integer              lock = Integer.valueOf(0);

public testClass(Context ctx)
{
    if (ctx != null)
        context = ctx.getApplicationContext();
    else
        context = null;

    synchronized(lock)
    {
        Log.v(at_data.TAG, "I_AM_IN=" + I_AM_IN);
        I_AM_IN = true;

      // Access resource
      // 
      // Multiple threads do enter here!

        Log.v(at_data.TAG, "I_AM_OUT=" + I_AM_IN);
        I_AM_IN = false;
    }
}

私はおそらく何かを見逃していましたが、動作するはずがない!?というドキュメントは見つかりませんでした.

出力:

I_AM_IN=false
I_AM_IN=true
I_AM_OUT=true
I_AM_OUT=false

ただし、ほとんどの場合は次のようになります。

I_AM_IN=false
I_AM_OUT=true
I_AM_IN=false
I_AM_OUT=true
4

2 に答える 2

3

あなたのコメントに基づいて、問題はロックを変更していることです。Integer オブジェクトの値をインクリメントすることはできません。整数は不変であるため、「インクリメント」するたびに、ロックを別のロックに置き換えます。

lock = new Integer(lock.intValue() + 1);

ファイナル をロックとして使用new Object()し、別の変数を使用してカウントを保持します。または、AtomicInteger を使用します。セマフォもあなたが探しているクラスかもしれません。

経験則: ロックは常に最終的なものでなければなりません。また、共有オブジェクトをロックとして使用しないでください (Integer.valueOf(0)は共有オブジェクトです。valueOf(0)少なくとも一部の VM 実装では、常に同じ Integer インスタンスを返すためです)。

于 2013-02-24T09:40:47.960 に答える
1

プライベート最終ロック オブジェクトを使用する必要があります。

于 2013-02-24T09:35:34.343 に答える