Javaでのタイマーの致命的な欠点(学習方法を使用)

目次

前書き

ケース1:タイマーがHello World!を出力します。

スレッドは死んでいませんか?

ケース2:シングルスレッドの問題

タイマーの実用的なアプリケーションシナリオ

学習方法の経験

総括する


前書き


この記事を書くべきかどうか悩んでいますが、タイマーの使い方が比較的簡単なので書きたくないですし、2つ目はインタビューでよく聞かないことです。後で、問題の分析をみんなと共有して、学習の過程で誰もが参照できるようにしたいと思いました。ほとんどの人、特に友達の方は、学習態度に問題はないと思います。私のブログ投稿を読んでいます。あなたに狂った褒め言葉を与えなさい。次のステップは学習方法ですが、最近相談してくれた小さな友達の学習姿勢が間違っていたので、Javaのタイマーを使って学習方法を整理しました。高層ビルは地面にそびえ立つので、私はいつも最も簡単で、最も簡単で、最も単純なケースを最初に使用します!まずHelloWorldを作りましょう!

image.png

 

 

 

 

ケース1:タイマーがHello World!を出力します。


import java.text.ParseException;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

/**
 * @author :jiaolian
 * @date :Created in 2021-01-05 20:42
 * @description:Timer启动后内置线程不销毁
 * @modified By:
 * 公众号:叫练
 */
public class TimerThreadNoStopTest {

    //TimerTask为抽象类,继承TimerTask类必须要实现里面抽象方法
    private static class Task extends TimerTask {
        @Override
        public void run() {
            System.out.println("hello world!");
        }
    }

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

        Timer timer = new Timer();
        Task task = new Task();
        long currenTime = System.currentTimeMillis();
        //提交Task线程;程序按传入日期运行
        timer.schedule(task,new Date(currenTime));
    }
}

上記のプログラムコードのように、タイマーはタスクタスクを送信し、currenTimeの現在の時刻を渡します。コンソールは、スケジュールで渡された2番目のパラメーターが新しい日付(currenTime + 2000)の場合、すぐに「helloworld!」を出力します。 2mの遅延タスクタスクを実行するための簡単な使用方法についてはここではあまり説明しませんが、学習プロセスで疑問が生じた場合は、コードテストをさらに作成する必要があります。これはコードを理解する上で不可欠な部分です。理解できると思います。もう書きません。学習中のように、少し疑問がある場合は、理解できることもあるので、すぐに手作業でコードをテストしますが、理解できない場合もあります。本当です、コードだけが検証できます!次の図は、プログラムコンソールの印刷結果です。誰もがそれを実行すると、問題が発生します。プログラムの実行が停止することはありません。つまり、プログラムが停止することはありません。この結果の原因は何ですか?

image.png

 

スレッドは死んでいませんか?


理由分析:次の図に示すように、メインスレッドはTimer timer = new Timer();を実行し、新しい子スレッドタイマーが作成されます。タイマースレッドは、キュー内のタスクtask [1]をエンドレスループで受け取ります。キューは実際には配列ですTaskQueueを実装するために、キューにタスクがない場合、タイマースレッドはメインスレッドがスケジュールを呼び出してタスクを送信するまで待機します。メインスレッドはタスクをTaskQueueキュー配列に追加し、タイマースレッドに通知します。タスクを実行し、キュー内の最初のタスクを削除します。メインスレッドが時間指定タスクを送信すると、タスクがキューに再度追加されます。タスクの実行後、この時点でキューが空の場合、タイマーはスレッドはタスクがキューに送信されるのを待ち続け、上記のプロセスをループします。タイマースレッドを終了する場合は、cancelメソッドを呼び出して無限ループを終了できますスレッドが停止しない理由は、タイマースレッドがメインスレッドからのタスクの送信を待機しており、タイマースレッドとメインスレッド間の通信はwait / notifyを呼び出すことによって実現されるためです。生産者/消費者の場合に詳しく紹介しましたが、ここでは繰り返し説明しません。「鶏産卵の例」の記事をご覧くださいこのプロセス中に、タイマーがシングルスレッドであることがわかりましたシングルスレッドの何が問題になっていますか?シングルスレッドも間違っていますか?質問を考えてみましょう。タイマーが1つのスレッドで2つのタスクを送信した場合はどうなりますか?以下のコードを見てみましょう!

image.png

 

 

ケース2:シングルスレッドの問題


import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

/**
 * @author :jiaolian
 * @date :Created in 2021-01-06 10:53
 * @description:多任务执行测试,任务只能顺序执行;
 * @modified By:
 * 公众号:叫练
 */
public class MultTaskExecuteTest {


    private static final SimpleDateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private static class  MyTask1 extends TimerTask {

        @Override
        public void run() {
            System.out.println("task1 begin:"+SIMPLE_DATE_FORMAT.format(new Date()));
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("task1 end:"+SIMPLE_DATE_FORMAT.format(new Date()));
        }
    }

    private static class  MyTask2 extends TimerTask {

        @Override
        public void run() {
            System.out.println("task2 begin:"+SIMPLE_DATE_FORMAT.format(new Date()));
            System.out.println("task2 end:"+SIMPLE_DATE_FORMAT.format(new Date()));
        }
    }


    public static void main(String[] args){
        Timer timer = new Timer();
        MyTask1 myTask1 = new MyTask1();
        MyTask2 myTask2 = new MyTask2();
        long curTime = System.currentTimeMillis();
        System.out.println("当前时间:"+SIMPLE_DATE_FORMAT.format(curTime));
        timer.schedule(myTask1,new Date(curTime));
        //myTask1执行时间过长,myTask2 被执行时间会被延迟;
        timer.schedule(myTask2,new Date(curTime+1000));
    }

}

上記のプログラムコードに示すように、タイマースレッドは2つのタスクmyTask1、myTask2を送信し、myTask1はすぐに実行され、myTask2は1秒間遅延するようにスケジュールされ、myTask1は実行中に10秒間休止します。タスクを観察します。下図のように実行時間myTask2myTask1のタスクが実行された後、タスクが実行されます。実際、myTask2は1秒だけ遅延しますが、結果は10秒遅延します。これは、 timerはタスクをシリアル化し、myTask2の実行を遅らせるので、Timerは軽量のタイミングに適しています。タスク、多数のタスクが設定されている場合、実行が遅れる可能性があります

image.png

 

 

タイマーの実用的なアプリケーションシナリオ


日々のシステム開発では、毎日午前2時にデータベース内のテーブルのガベージデータをクリーンアップしたり、ページ表示デバイス(サーバー)の稼働状態など、繰り返し実行する必要のある同様のタスクに遭遇したと思います。3秒ごとにデバイスステータスインターフェイス呼び出す必要がありますデバイスステータスなどを照会するには、これらの関数の開発にタイマーを使用する必要があります。もちろん、タイマータイマーにも独自の欠点があります。たとえば、単一の後で、スレッドプール内のタイマーがマルチスレッドであり、タイマーを最適化できることについて説明します。したがって、タイマーを習得することで、後で高度なコンテンツを学習するための強固な基盤が築かれます。理由を知り、理由を知ることで、実用化に重宝します!

 

 

学習方法の経験


最近の記事でマルチスレッドの分析に多くのエネルギーを費やし、可視性、原子性、産卵鶏、消費の問題などの問題について議論していることがわかります。これらの機能はマルチスレッドを理解するための基礎であるためです。意見。それも非常に重要なので、繰り返し書くことはそれほど多くないと思います。これまで、2〜3年の実務経験を持つ初心者や子供たちから、Javaの学習方法についてよく聞かれました。たくさんの子供用の靴が出てきたらすぐにスプリングブートを実行します。、Ssmプロジェクト、これを実行することはお勧めしません。最初にサーブレット、mvcのアイデアを理解する必要があります。これが、プロジェクトを実行する前の基礎です。彼らへの私のアドバイスは、しっかりとした基盤を持ち、ReentrantLockソースコード、スレッドプールフレームワークなどの高度な知識やフレームワークを学ぶのではなく、ゲームをプレイするのと同じように、最初はより高いレベルの難易度をプレイすることです。傾斜が高いほど、あなたはより不快で面倒になります。本に直面することは言うまでもなく、これは始めから諦めるまでの本当のプロセスです。同時に、勉強するときに考えるだけでなく、自分でこの知識のポイントを渡すと思います。これだけでは不十分です。より多くのコードを記述し、より多くの練習をする必要があります。理解を深め、その過程での知識の記憶実は、たくさんの知識を理解しているように見えますが、それを実践しておらず、実際に理解していないのです。できる方法はお勧めしません。「tはそれを行う。私は私の学士号を卒業した後、7年間働いてきたとJavaの第一線の研究開発に従事してきた。、シニアJavaのR&Dエンジニアとして、私はまた、間にチームをもたらしたので、私はピットを歩きましたが、まだプログラムを学ぶ経験があります。これからもいくつかの経験と知識を整理して共有していきます。皆さんに、皆さんが私をフォローしてくれることを願っています。私は練習と呼ばれています。スローガンを呼んだら練習を始めてください!

要約すると、2つの文があります。より多くのことを行う、しっかりとした基盤を築く、シンプルに始める、そしてゆっくりと深くなる!

 

 

総括する


コードを使用して、タイマータイマー送信タスクを簡単に説明し、タイマーがシングルスレッドの軽量タイミングタスクであることを説明します。これが欠点です。スペースに限りがあるので、タイミング実行、遅延実行、タイマーキャンセル方法など、コードを使わずに投稿したタイマーの方法はまだたくさんありますので、本で一つずつ実行してほしいと思いますので、お勧めしますこのマルチスレッド入門書「JavaMore「スレッドプログラミングのコアテクノロジー」」は、主にケースに基づいており、特に難しいケースはなく、初心者の方にも適しています。pfdバージョンが必要な場合は、私に連絡してください!よろしければ、よろしくお願いします。私の名前はリアン[公式アカウント]です。電話して練習します。

image.png

 

 

おすすめ

転載: blog.csdn.net/duyabc/article/details/112346052