1

私が持っているとしましょう -

public class ThreadingIssue {
    public B b = new B();
}

class B{
    private final Object lock = new Object();

    public void someMethod(int timeOut){
        synchronized(lock){
            try{
                lock.wait(timeOut);
            }catch(Exception e){
            }
            // some task..
            lock.notifyAll();
        }
    }
}

class Thread1 implements Runnable{
    private ThreadingIssue t;

    public Thread1(ThreadingIssue issue) {
        t = issue;
    }

    public void run(){
        while(true){
              t.b.someMethod(5000);
        }
    }
}

class Thread2 implements Runnable{
    private ThreadingIssue t;

    public Thread2(ThreadingIssue issue){
        t = issue;
    }

    public void run(){
        try{
            Thread.sleep(2000);
        }catch(Exception e){
        }
        t.b = null;
    }
}

Thread1 が B の内部someMethod(5000)にあり、ロックを待っていて、Thread2 が B のオブジェクトを null にした場合、Thread1 はどうなるでしょうか? Thread1がどの例外をスローするかどうかはわかりません..助けはありますか?

4

2 に答える 2

3

2 番目のスレッドは、実行中のメソッドを持つオブジェクトへの参照を保持します (そうしないと、インスタンス メソッドを実行できません)。そのため、GC はオブジェクトを破棄できないため、例外が発生する可能性はありません。

あなたのコードをより明確にするために、あなたがそうするとき

t.b.someMethod(5000)

内部で JVM がt.b式 (オブジェクトへの参照) を処理するため、参照カウントは 0 ではありません。

于 2012-12-16T13:34:28.930 に答える
1

SJuan76 と op の議論の要約:
t への参照が 2 つあるように見えますが、b への参照は 1 つだけです (t 内のもの)。t はスレッドが独立して保持しているため、解放されません。ただし、参照が無効になると参照カウントがゼロになるため、b は削除される場合があります (gc によって異なります)。
そのため、Thread2 は NullPointerException をスローする可能性があります。

編集:
someMethod() 内では、thisポインターがスタックに保持され、少なくとも ref カウントが 1 になるため、b オブジェクトは解放されません。thisメンバーメソッドのすべてが引数として 取得されるため、メンバーメソッドの実行ごとに同じことが言えます。

NullPointerException が発生しても、オブジェクトがすでにファイナライズ/解放されているわけではなく、使用している参照が null であることに注意してください。GC がオブジェクトを実際に解放するには、時間がかかる場合があります。

于 2012-12-16T16:21:04.980 に答える