2

1ミリ秒で何かを実行してから終了するようにスケジュールする必要があるこの単純なJavaコードがあります。

import java.util.*;

class A {
    public static void main(String[] args) {
        new Timer().schedule(new TimerTask() {
            public void run() {
                System.out.println("hello");
            }
        }, 1);
        System.out.println("hi");
    }
}

それは決してやめません。なんで?

$ javac A.java && java A
hi
hello

スケジュールを設定するコードを削除すると、機能します。なんで?

4

1 に答える 1

2

java.util.Timerのドキュメントには次のように書かれています。

呼び出し元がタイマーのタスク実行スレッドを迅速に終了したい場合、呼び出し元はタイマーの cancel メソッドを呼び出す必要があります。

それがあなたがすべきことです。Robert Harveyは、質問の下のコメントとして、その方法を示すものにリンクしています。

あなたのコードを使用すると、これはあなたのコードと同じものを出力しましたが、その後終了しました:

public static void main(String[] args) {
    final Timer timer = new Timer();
    timer.schedule(new TimerTask() {
        public void run() {
            System.out.println("hello");
            timer.cancel();
        }
    }, 1);
    System.out.println("hi");        
}

または、次のようにタイマーを作成して、タイマーをデーモンにすることもできます。

public static void main(String[] args) {
    final Timer timer = new Timer(true);
    timer.schedule(new TimerTask() {
        public void run() {
            System.out.println("hello");
        }
    }, 1);
    System.out.println("hi");
}

問題は、タスクが実行される前にこれが終了し、次のような出力が得られることです。

hi
<exit>

javadocpublic Timer(boolean isDaemon)は理由を説明しています:

関連付けられたスレッドをデーモンとして実行するように指定できる新しいタイマーを作成します。タイマーを使用して繰り返しの「メンテナンス アクティビティ」をスケジュールする場合、デーモン スレッドが呼び出されます。これは、アプリケーションが実行されている限り実行する必要がありますが、アプリケーションの寿命を延ばすべきではありません。

于 2013-05-23T20:59:12.593 に答える