連載
» 2007年03月28日 00時00分 公開

プログラマーの常識をJavaで身につける(4):OSとプログラミングの「時間」に関する常識 (3/3)

[伊賀敏樹,NTTデータ ビジネスブレインズ]
前のページへ 1|2|3       

日時を文字列へ変換[java.text.SimpleDateFormat]

 日時型を文字列に変換するには、java.text.SimpleDateFormatクラスを利用します。ここでは、java.util.Date型から、年月日時分秒からなる文字列へ変換する例を示します(※フォーマットの指定方法などの詳細は、SimpleDateFormatクラスのAPIドキュメントをご参照ください)。

SimpleDateFormatSample.java
import java.text.SimpleDateFormat;
import java.util.Date;

public class SimpleDateFormatSample {
    public static void main(final String[] args) {
        final Date current = new Date();

         // java.util.Date → 文字列フォーマット
        final SimpleDateFormat sdf
            = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

        
        System.out.println(sdf.format(current));
    }
}

実行結果

2007/03/20 14:42:15


編集部注SimpleDateFormatクラスについて詳しく知りたい読者は、Java TIPS の「言語に依存しない方法で日付・時刻をフォーマット」をご参照ください

タイマーとタスクって何だ?

 ここからは話を変えて、指定の時間だけスレッドの実行を止めたり、あるいは指定の時間間隔でスレッドを動作させるためのプログラミングを紹介していきます。

スレッドの一時的な実行停止

 まず、スレッドの一時的な実行停止について学んでいきましょう。スレッドの一時停止を見る前に、一時停止とは関係のない、単純な繰り返しのプログラミングを見ていきます。下記のソースコードを実行してください。

SleepSample.java
public class SleepSample {
    public static void main(final String[] args) {
        for (int loopCount = 0; loopCount < 10; loopCount++) {
            System.out.println("処理" + (loopCount + 1) + "回目");
        }
    }
}

実行結果

処理1回目

処理2回目

処理3回目

処理4回目

処理5回目

処理6回目

処理7回目

処理8回目

処理9回目

処理10回目


 実行すると、即時に処理1回目から処理10回目まで繰り返されます。ごく普通の挙動ですね。

 次に、これをゆっくり実行するように変更してみましょう。下記のソースコードを実行してください。

SleepSample.java(変更後)
public class SleepSample {
    public static void main(final String[] args) {
        for (int loopCount = 0; loopCount < 10; loopCount++) {
            try {
                // 毎回 1秒 実行を一時停止する。
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                System.out.println("スレッドの一時停止中に、"
                + "予期せぬ割込が発生しました。:" + e.toString());
            }
            System.out.println("処理" + (loopCount + 1) + "回目");
        }
    }
}

 java.lang.Thread.sleep(ミリ秒)メソッドにより、スレッドの実行を一時停止できることを確認してください。

[java.util.Timer]と[java.util.TimerTask]で定期的な実行

 先の例では、プログラム上に一時停止の実装が記述されていました。そして、それにより定期的な実行が実現できていた、と見ることもできます。

 Java言語APIには、このような定期的な実行や定時実行を実現するためのjava.util.Timerクラスがありますので、これを見ていきましょう。java.util.Timerクラスを利用する場合には、Timerクラスとjava.util.TimerTaskクラスの2つを組み合わせて利用します。

MyTask.java(タスク)
import java.util.TimerTask;

public class MyTask extends TimerTask {
    private long fLoopCount = 0;
    
    public void run() {
        System.out.println("処理" + (++fLoopCount) + "回目");
    }
}

TimerSample.java(タスクを呼び出す側)
import java.util.Timer;

public class TimerSample {
    public static void main(final String[] args) {
        final Timer timer = new Timer();

        System.out.println("5秒後に一度タスク実行し、"
            + " 続けて毎秒タスク実行を行います。");

        timer.schedule(new MyTask(), 5000, 1000);

        try {
            // スレッドを15秒間、一時的に実行停止します。
            Thread.sleep(15000);

            System.out.println(
                "15秒経過したので、mainを終了します。");
        } catch (InterruptedException e) {
            System.out.println(
                "割込例外が発生しました。処理中断します。:"                 
                + e.toString());
            e.printStackTrace();
        }
    }
}

 この例では、5秒後にタスクを実行し、以降毎秒タスクを実行するようなサンプルとなっています。上記2つのソースコードを実行してください。

実行結果

5秒後に一度タスク実行し、続けて毎秒タスク実行を行います。

処理1回目

処理2回目

処理3回目

処理4回目

処理5回目

処理6回目

処理7回目

処理8回目

処理9回目

処理10回目

15秒経過したので、mainを終了します。

処理11回目

処理12回目

処理13回目

処理14回目

処理15回目

処理16回目

処理17回目

処理18回目 ……以降、半永久的に動作し続けます。


 5秒経過した後、前のThread.sleepの例で確認したのと同様の実行結果が得られます。ところが、「15秒経過したので、mainを終了します。」のメッセージが出力された後も引き続き動作し続けています。

 この実行を停止させるためには、該当のJavaVMを停止させる必要があります。Eclipseであれば、コンソールビュー上の終了(赤い四角)ボタンを押して停止させてください。

図7 コンソールビュー(実行中) 図7 コンソールビュー(実行中)

 これはTimerクラスのパラメータなしコンストラクタを利用した場合には、スレッドが動作し続けるような仕様になっているためです。

Timerを完全に止めるには?

 mainスレッドが停止したら、Timerも停止するようにするためには、下記のように変更します。下記のソースコードを実行してください。

TimerSample.java(変更後)
import java.util.Timer;

public class TimerSample {
    public static void main(final String[] args) {

        // Timerコンストラクタにtrueを渡して
        // デーモンスレッド化を行うよう変更

        final Timer timer = new Timer(true);


        System.out.println("5秒後に一度タスク実行し、"
            + " 続けて毎秒タスク実行を行います。");

        timer.schedule(new MyTask(), 5000, 1000);

        try {
            // スレッドを15秒間、一時的に実行停止します
            Thread.sleep(15000);

            System.out.println(
                "15秒経過したので、mainを終了します。");
        } catch (InterruptedException e) {
            System.out.println(
                "割込例外が発生しました。処理中断します。:"
                + e.toString());
            e.printStackTrace();
        }
    }
}

実行結果

5秒後に一度タスク実行し、続けて毎秒タスク実行を行います。

処理1回目

処理2回目

処理3回目

処理4回目

処理5回目

処理6回目

処理7回目

処理8回目

処理9回目

処理10回目

15秒経過したので、mainを終了します。

処理11回目


 mainが終了すると、JavaVMが終了することを確認してください。Eclipseでは、終了ボタンが灰色に戻っている灰色に戻っていることでも確認できます。

図8 コンソールビュー(実行終了) 図8 コンソールビュー(実行終了)

次回は「国際化プログラミング」の常識について

 次回は、国際化プログラミングの常識についてです。java.util.Localejava.util.TimeZoneクラスでロケールの概念、java.util.Currencyクラスで通貨などについて学んでいきましょう。

筆者紹介

blanco Framework(コミッタ)

伊賀 敏樹(いが としき)
ハンドル:いがぴょん

1968年生まれ。現在、NTTデータ ビジネスブレインズ 第一SI事業部 ソリューショングループ所属。システム開発の技術支援などに従事する。仕事におけるJava言語とのかかわりは1998年から。 現在 blanco Frameworkというオープンソースによるソースコード自動生成タイプの開発フレームワーク提供に取り組んでいる。 趣味はヴァイオリン演奏。アマチュアオーケストラで演奏することもある。

ホームページ
いがぴょんの日記ウェブページv2(1996年から続けているWeb日記)

主な著書
やさしく学ぶ基礎からのJDBC
Javaプログラミング[アプリケーション編]ステップアップラーニング



前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。