Thread.isAlive() は 実際にThread が GC されてからでないと
Falseにならないと思ってました。

でも、次の処理がない場合は 「生存していない」扱いになることを発見。
知らなかった。。。

以下検証コードです。

public class Test{

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<span class="synType">public</span> <span class="synType">static</span> <span class="synType">void</span> main(String[] args) {
    <span class="synStatement">new</span> TestChiledThread(Thread.currentThread()).start();
    <span class="synStatement">try</span> {
        Thread.sleep(<span class="synConstant">1000</span>);
    } <span class="synStatement">catch</span> (InterruptedException ex) {
        Logger.getLogger(TestChiledThread.<span class="synType">class</span>.getName()).log(Level.SEVERE, <span class="synConstant">null</span>, ex);
    }
    System.out.println(<span class="synConstant">&quot;main end.&quot;</span>);
    System.gc();
}

<span class="synPreProc">@Override</span>
<span class="synType">protected</span> <span class="synType">void</span> finalize() <span class="synType">throws</span> Throwable {
    System.out.println(<span class="synConstant">&quot;finalize!&quot;</span>);
    <span class="synType">super</span>.finalize();
}

}

class TestChiledThread extends Thread{ private Thread current = null; public TestChiledThread(Thread current){ this.current = current; } @Override public void run(){ for(int i = 0 ; i < 5 ; i++){ try { System.out.println( "status:" + current.getState() + " isAlive:" + current.isAlive() + " instance-null?:" + (current == null)); Thread.sleep(1000); } catch (InterruptedException ex) { Logger.getLogger(TestChiledThread.class.getName()).log(Level.SEVERE, null, ex); } } } }

結果こうなりました

run:
status:TIMED_WAITING isAlive:true instance-null?:false
main end.
status:RUNNABLE isAlive:true instance-null?:false
status:TERMINATED isAlive:false instance-null?:false
status:TERMINATED isAlive:false instance-null?:false
status:TERMINATED isAlive:false instance-null?:false

ビルド成功(合計時間: 5秒)