1

ユーザーが指定したタイミング要件に従って、スレッド内でタスクの実行を完了するための非常に単純なおもちゃのプログラムを作成しました。コードと出力例を以下に示します。コードを実行するたびに、タスクの完了時間は、ユーザーが指定した時間の + デルタ範囲内になります。たとえば、ユーザーが 5 秒でプログラムを完了したい場合、コードが実行されている CPU に応じて 5093 または 5012 ミリ秒で完了する場合があります。特定の CPU が特定のバージョンの JVM に提供する最小レイテンシーを自動的に決定できるコードを追加したいと考えています。そのインストルメンテーション コードに基づいて、デルタの値を : のif (( taskRunTime > patience+delta) && t.isAlive())ように行に追加して、システムがタスク実行タイミングの精度を高めることができます。いくつかの提案をしてください。

コード:

public class ThreadExample 
{


    static void threadMessage(String message) 
    {
        String threadName = Thread.currentThread().getName();
        System.out.format("%s: %s%n", threadName, message);
    }

    private static class MessageLoop implements Runnable 
    {
        public void run() 
        {
            String importantInfo[] = 
            {
                "A new integrated approach to programming",
                "The innovative approach of the system",
                "The input of a tracking system",
                "A simulation system is then used for collision checking"
            };
            try 
                {
                    for (int i = 0; i < importantInfo.length; i++) 
                        {

                            Thread.sleep(4000);
                            threadMessage(importantInfo[i]);
                        }
                } 
                catch (InterruptedException e) 
                    {
                        threadMessage("I wasn't done!");
                    }
        }
    }

    public static void main(String args[]) throws InterruptedException 
    {


        //Delay, in milliseconds before we interrupt MessageLoop
        long patience = 1000 * 60 * 60;

        //If command line argument present, gives patience in seconds.
        if (args.length > 0) 
        {
            try {
                patience = Long.parseLong(args[0]) * 1000;
            } catch (NumberFormatException e) {
                System.err.println("Argument must be an integer.");
                System.exit(1);
            }

        }

        threadMessage("Starting MessageLoop thread");
        long startTime = System.currentTimeMillis(),taskRunTime=0;
        Thread t = new Thread(new MessageLoop());
        t.start();

        threadMessage("Waiting for MessageLoop thread to finish");
        //loop until MessageLoop thread exits
        while (t.isAlive()) 
        {
            threadMessage("Still waiting...");
            //Wait maximum of 1 second for MessageLoop thread to finish.
            t.join(100);
            taskRunTime=System.currentTimeMillis() - startTime;
            if (( taskRunTime > patience) && t.isAlive()) 
            {
                threadMessage("Tired of waiting...task is running longer than the patience you set or the default!");
                t.interrupt();
                t.join();
            }

        }
        threadMessage("Finally out of thread!");
        System.out.println("Time to complete task="+taskRunTime+"ms");

    }
}

Intel Centrino 1.7 Ghz マシンからのサンプル出力 ( Java HotSpot(TM) Client VM (build 10.0-b23、混合モード) )

java -jar ThreadExample.jar 5
main: Starting MessageLoop thread
main: Waiting for MessageLoop thread to finish
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
Thread-0: A new integrated approach to programming
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Still waiting...
main: Tired of waiting...task is running longer than the patience you set or the default!
Thread-0: I wasn't done!
main: Finally out of thread!
4

2 に答える 2

3

また、Thread.sleepの動作や、スレッド化とJavaに関連するその他の役立つ可能性のあるものについてもいくつか書いています。

簡単に言うと、得られる粒度は多くの要因に依存し、その一部は動的です。あなたが提案するようにそれを計装することは一つの方法です。インストルメンテーションについて考える必要があることは次のとおりです。

  • 与えられた条件下での実際の睡眠と要求された行動の振る舞い(異なる条件下でのいくつかの典型的な振る舞いの実例については私の記事を参照してください)
  • 与えられた条件下でのスレッド割り込み待ち時間(CPU負荷、システムのスケジューリングポリシーに部分的に依存します...)

また、制御ループを改善して、基本的に(a)必要な時間スリープし(ループ内で、時間を確実にスリープさせる)、(b)タイムアウト後にスレッドを中断するようにすることを検討してください。

ところで、タイミングには常にSystem.nanoTime()を使用してください。そうしないと、一部のシステムではSystem.currentTimeMillis()の粒度が低いため、混乱するだけです。

于 2009-08-11T22:07:26.993 に答える
0

Java Real Time を調べることをお勧めし ます: http://en.wikipedia.org/wiki/Real_time_Java /overview.html

Java 1.5 以降は独自のスレッドを作成するべきではありません

于 2009-08-11T21:47:44.317 に答える