国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

多線程---定時(shí)器

這篇具有很好參考價(jià)值的文章主要介紹了多線程---定時(shí)器。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

什么是定時(shí)器?

定時(shí)器的功能和“鬧鐘”類似,代碼中的定時(shí)器通常都是“多長(zhǎng)時(shí)間之后,執(zhí)行某個(gè)動(dòng)作”。

定時(shí)器的實(shí)現(xiàn)

標(biāo)準(zhǔn)庫(kù)中的定時(shí)器

        // 標(biāo)準(zhǔn)庫(kù)的定時(shí)器  執(zhí)行完任務(wù)之后線程不會(huì)退出  需要手動(dòng)殺死線程
    public static void main(String[] args) {
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("執(zhí)行第一次定時(shí)器任務(wù)");
            }
        },3000);

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("執(zhí)行第二次定時(shí)器任務(wù)");
            }
        },4000);

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("執(zhí)行第三次定時(shí)器任務(wù)");
            }
        },5000);

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("執(zhí)行第四次定時(shí)器任務(wù)");
            }
        },6000);

        System.out.println("定時(shí)器啟動(dòng)");
    }

注:

  1. 一個(gè)定時(shí)器可以安排多個(gè)任務(wù)。
  2. 調(diào)用schedule安排任務(wù)時(shí),一定要重寫run方法,明確任務(wù)內(nèi)容
  3. 定時(shí)器開(kāi)啟后不會(huì)自動(dòng)結(jié)束,得手動(dòng)殺死進(jìn)程

自己實(shí)現(xiàn)一個(gè)定時(shí)器

版本一:實(shí)現(xiàn)簡(jiǎn)單的定時(shí)器

  • schedule方法是用來(lái)描述任務(wù)內(nèi)容的。第一個(gè)參數(shù)是:任務(wù)內(nèi)容;第二個(gè)參數(shù)是:任務(wù)多長(zhǎng)時(shí)間后執(zhí)行
	public MyTask(Runnable runnable, long delay){
        this.runnable = runnable;
        this.time = System.currentTimeMillis() + delay;
    }

	public void schedule(Runnable runnable,long delay){
        MyTask myTask = new MyTask(runnable, delay); 
    }
  • 用什么數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)任務(wù)呢?

    我們首先要考慮的是要讓任務(wù)設(shè)置時(shí)間最短的先執(zhí)行,這就有個(gè)優(yōu)先級(jí)的問(wèn)題,所以使用優(yōu)先級(jí)隊(duì)列

    同時(shí),我們通常都會(huì)使用多個(gè)線程來(lái)執(zhí)行這些設(shè)置的任務(wù),就要保證線程安全。

    綜上,我們最后決定使用優(yōu)先級(jí)阻塞隊(duì)列來(lái)存儲(chǔ)任務(wù)

  • 我們創(chuàng)建一個(gè)專門的線程來(lái)執(zhí)行定時(shí)器里的任務(wù)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-715521.html

//最基礎(chǔ)的定時(shí)器完成
class MyTimer{
    private PriorityBlockingQueue<MyTask> priorityBlockingQueue = new PriorityBlockingQueue<>();



    public MyTimer(){
        Thread thread = new Thread(() -> {
            while (true){
                try {
                    MyTask myTask = priorityBlockingQueue.take();

                    if (System.currentTimeMillis() >= myTask.getTime()){
                        myTask.getRunnable().run();
                    }else {
                        priorityBlockingQueue.put(myTask);

                    }

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }


            }
        });
        thread.start();
    }

    private void schedule(Runnable runnable,long delay){
        MyTask myTask = new MyTask(runnable,delay);
        priorityBlockingQueue.put(myTask);
    }
}

版本二:解決thread線程的忙等問(wèn)題

  • 當(dāng)定時(shí)器啟動(dòng)后有一個(gè)問(wèn)題:不管任務(wù)時(shí)間有多久,thread線程一直執(zhí)行,會(huì)占用CPU資源。我們想個(gè)辦法讓它在任務(wù)時(shí)間還沒(méi)到的時(shí)候停下來(lái),就要使用wait-notify
class MyTimer{
    private PriorityBlockingQueue<MyTask> priorityBlockingQueue = new PriorityBlockingQueue<>();

    private Object locker = new Object();


    public MyTimer(){
        Thread thread = new Thread(() -> {
            while (true){
                try {
                    MyTask myTask = priorityBlockingQueue.take();

                    if (System.currentTimeMillis() >= myTask.getTime()){
                        myTask.getRunnable().run();
                    }else {
                        priorityBlockingQueue.put(myTask);
                        synchronized (locker){
                            locker.wait(myTask.getTime() - System.currentTimeMillis());
                        }

                    }

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }


            }
        });
        thread.start();
    }

    private void schedule(Runnable runnable,long delay){
        MyTask myTask = new MyTask(runnable,delay);
        priorityBlockingQueue.put(myTask);
    }
}

版本三:解決漏掉任務(wù)的問(wèn)題

  • 又一個(gè)問(wèn)題:如果schedule線程中新添加了一個(gè)任務(wù) 執(zhí)行時(shí)間比wait時(shí)間短 不就錯(cuò)過(guò)了嘛。使用notify
class MyTimer{
    private PriorityBlockingQueue<MyTask> priorityBlockingQueue = new PriorityBlockingQueue<>();

    private Object locker = new Object();


    public MyTimer(){
        Thread thread = new Thread(() -> {
            while (true){
                try {
                    MyTask myTask = priorityBlockingQueue.take();

                    if (System.currentTimeMillis() >= myTask.getTime()){
                        myTask.getRunnable().run();
                    }else {
                        priorityBlockingQueue.put(myTask);
                        synchronized (locker){
                            locker.wait(myTask.getTime() - System.currentTimeMillis());
                        }

                    }

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }


            }
        });
        thread.start();
    }

    private void schedule(Runnable runnable,long delay){
        MyTask myTask = new MyTask(runnable,delay);
        priorityBlockingQueue.put(myTask);
        synchronized (locker){
            locker.notify();
        }
    }
}

版本四:解決notify先執(zhí)行的問(wèn)題

  • 如果notify先執(zhí)行了 take在notify之前執(zhí)行 也就是說(shuō)放進(jìn)去了新的元素 但是take這邊的線程沒(méi)感覺(jué)到不就還沒(méi)起到效果嘛。 擴(kuò)大鎖的范圍
class MyTimer{
    private PriorityBlockingQueue<MyTask> priorityBlockingQueue = new PriorityBlockingQueue<>();

    private Object locker = new Object();


    public MyTimer(){
        Thread thread = new Thread(() -> {
            while (true){
                try {
                    synchronized (locker) {
                        MyTask myTask = priorityBlockingQueue.take();

                        if (System.currentTimeMillis() >= myTask.getTime()) {
                            myTask.getRunnable().run();
                        } else {
                            priorityBlockingQueue.put(myTask);

                            locker.wait(myTask.getTime() - System.currentTimeMillis());


                        }
                    }

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }


            }
        });
        thread.start();
    }

    public void schedule(Runnable runnable,long delay){

        MyTask myTask = new MyTask(runnable, delay);
        priorityBlockingQueue.put(myTask);
        //這里起到的作用就是 刷新一下  看看隊(duì)列中有沒(méi)有執(zhí)行時(shí)間更早的任務(wù)   有兩種情況
        //1. 先放進(jìn)去再刷新查看    先放進(jìn)去最開(kāi)始沒(méi)注意到也沒(méi)事兒  刷新的時(shí)候就會(huì)注意到重新計(jì)算wait時(shí)間
        //2. 先查看再放進(jìn)去        會(huì)死鎖(把notify的鎖范圍放大)   在一開(kāi)始隊(duì)列里沒(méi)有數(shù)據(jù)的時(shí)候  會(huì)等待添加元素 但添加元素得獲取到鎖  此時(shí)阻塞的時(shí)候已經(jīng)鎖上了take
        //   沒(méi)有人釋放鎖 所以 死鎖了
        synchronized (locker) {
            locker.notify();
        }
    }
}

到了這里,關(guān)于多線程---定時(shí)器的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Java多線程案例之定時(shí)器

    Java多線程案例之定時(shí)器

    定時(shí)器是一種實(shí)際開(kāi)發(fā)中非常常用的組件, 類似于一個(gè) “鬧鐘”, 達(dá)到一個(gè)設(shè)定的時(shí)間之后, 就執(zhí)行某個(gè)指定好的代碼. 比如網(wǎng)絡(luò)通信中, 如果對(duì)方 500ms 內(nèi)沒(méi)有返回?cái)?shù)據(jù), 則斷開(kāi)連接嘗試重連. 比如一個(gè) Map, 希望里面的某個(gè) key 在 3s 之后過(guò)期(自動(dòng)刪除). 類似于這樣的場(chǎng)景就需要

    2024年02月20日
    瀏覽(24)
  • 【Java | 多線程案例】定時(shí)器的實(shí)現(xiàn)

    【Java | 多線程案例】定時(shí)器的實(shí)現(xiàn)

    個(gè)人主頁(yè):兜里有顆棉花糖 歡迎 點(diǎn)贊?? 收藏? 留言? 加關(guān)注??本文由 兜里有顆棉花糖 原創(chuàng) 收錄于專欄【Java系列專欄】【JaveEE學(xué)習(xí)專欄】 本專欄旨在分享學(xué)習(xí)JavaEE的一點(diǎn)學(xué)習(xí)心得,歡迎大家在評(píng)論區(qū)交流討論?? Java中, Timer類 是用于計(jì)劃和執(zhí)行重復(fù)任務(wù)的類( Java標(biāo)準(zhǔn)

    2024年02月03日
    瀏覽(15)
  • 【Java】多線程案例(單例模式,阻塞隊(duì)列,定時(shí)器,線程池)

    【Java】多線程案例(單例模式,阻塞隊(duì)列,定時(shí)器,線程池)

    ?? Author: 老九 ?? 個(gè)人博客:老九的CSDN博客 ?? 個(gè)人名言:不可控之事 樂(lè)觀面對(duì) ?? 系列專欄: 單例模式是設(shè)計(jì)模式之一。代碼當(dāng)中的某個(gè)類,只能有一個(gè)實(shí)例,不能有多個(gè)。單例模式分為:餓漢模式和懶漢模式 餓漢模式表示很著急,就想吃完飯剩下很多碗,然后一

    2024年02月06日
    瀏覽(51)
  • Java 多線程系列Ⅳ(單例模式+阻塞式隊(duì)列+定時(shí)器+線程池)

    Java 多線程系列Ⅳ(單例模式+阻塞式隊(duì)列+定時(shí)器+線程池)

    設(shè)計(jì)模式就是軟件開(kāi)發(fā)中的“棋譜”,軟件開(kāi)發(fā)中也有很多常見(jiàn)的 “問(wèn)題場(chǎng)景”。針對(duì)這些問(wèn)題場(chǎng)景,大佬們總結(jié)出了一些固定的套路。按照這些套路來(lái)實(shí)現(xiàn)代碼可能不會(huì)很好,但至少不會(huì)很差。當(dāng)前階段我們需要掌握兩種設(shè)計(jì)模式: (1)單例模式 (2)工廠模式 概念/特征

    2024年02月09日
    瀏覽(25)
  • 【Java|多線程與高并發(fā)】定時(shí)器(Timer)詳解

    【Java|多線程與高并發(fā)】定時(shí)器(Timer)詳解

    在Java中,定時(shí)器 Timer 類是用于執(zhí)行定時(shí)任務(wù)的工具類。它允許你安排一個(gè)任務(wù)在未來(lái)的某個(gè)時(shí)間點(diǎn)執(zhí)行,或者以固定的時(shí)間間隔重復(fù)執(zhí)行。 在服務(wù)器開(kāi)發(fā)中,客戶端向服務(wù)器發(fā)送請(qǐng)求,然后等待服務(wù)器響應(yīng). 但服務(wù)器什么時(shí)候返回響應(yīng),并不確定. 但也不能讓客戶端一直等下去

    2024年02月07日
    瀏覽(20)
  • JAVAEE-定時(shí)器案例

    JAVAEE-定時(shí)器案例

    設(shè)置一個(gè)時(shí)間,當(dāng)時(shí)間到了的時(shí)候,定時(shí)器就會(huì)去自動(dòng)執(zhí)行某個(gè)邏輯. 這里timer里面的任務(wù)執(zhí)行完了也并不會(huì)結(jié)束,因?yàn)樗⒉恢朗欠襁€會(huì)添加新的任務(wù)進(jìn)去, 處在嚴(yán)陣以待的狀態(tài) 此時(shí)如果我們想要結(jié)束,應(yīng)該使用cancel主動(dòng)去結(jié)束. 1)需要有一個(gè)線程,負(fù)責(zé)掐時(shí)間,等任務(wù)到達(dá)合適的

    2024年02月05日
    瀏覽(26)
  • 【多線程】定時(shí)器,詳解定時(shí)器原理,讓大家更深刻的理解多線程

    【多線程】定時(shí)器,詳解定時(shí)器原理,讓大家更深刻的理解多線程

    前言: 大家好,我是 良辰丫 ,今天我們一起了解一下定時(shí)器,通過(guò)定時(shí)器來(lái)熟悉一下線程安全等相關(guān)知識(shí)點(diǎn).?????? ??個(gè)人主頁(yè):良辰針不戳 ??所屬專欄:javaEE初階 ??勵(lì)志語(yǔ)句:生活也許會(huì)讓我們遍體鱗傷,但最終這些傷口會(huì)成為我們一輩子的財(cái)富。 ??期待大家三連,關(guān)注

    2024年02月01日
    瀏覽(27)
  • 多線程---定時(shí)器

    定時(shí)器的功能和“鬧鐘”類似,代碼中的定時(shí)器通常都是“多長(zhǎng)時(shí)間之后,執(zhí)行某個(gè)動(dòng)作”。 注: 一個(gè)定時(shí)器可以安排多個(gè)任務(wù)。 調(diào)用schedule安排任務(wù)時(shí),一定要重寫run方法,明確任務(wù)內(nèi)容 定時(shí)器開(kāi)啟后不會(huì)自動(dòng)結(jié)束,得手動(dòng)殺死進(jìn)程 版本一:實(shí)現(xiàn)簡(jiǎn)單的定時(shí)器 schedule方法

    2024年02月08日
    瀏覽(23)
  • 多線程案例(3)-定時(shí)器

    大家好,我是曉星航。今天為大家?guī)?lái)的是 多線程案例三 相關(guān)的講解!?? 定時(shí)器是什么 定時(shí)器也是軟件開(kāi)發(fā)中的一個(gè)重要組件. 類似于一個(gè) “鬧鐘”. 達(dá)到一個(gè)設(shè)定的時(shí)間之后, 就執(zhí)行某個(gè)指定 好的代碼. 定時(shí)器是一種實(shí)際開(kāi)發(fā)中非常常用的組件. 比如網(wǎng)絡(luò)通信中, 如果對(duì)方

    2024年02月14日
    瀏覽(17)
  • 多線程案例 | 單例模式、阻塞隊(duì)列、定時(shí)器、線程池

    多線程案例 | 單例模式、阻塞隊(duì)列、定時(shí)器、線程池

    單例模式 單例模式是 設(shè)計(jì)模式 的一種 什么是設(shè)計(jì)模式? 設(shè)計(jì)模式好比象棋中的 “棋譜”,紅方當(dāng)頭炮,黑方馬來(lái)跳,針對(duì)紅方的一些走法,黑方應(yīng)招的時(shí)候有一些固定的套路,按照套路來(lái)走局勢(shì)就不會(huì)吃虧,也就發(fā)明了一組\\\"棋譜\\\",稱為設(shè)計(jì)模式 軟件開(kāi)發(fā)中也有很多常見(jiàn)

    2024年02月15日
    瀏覽(26)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包