欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中定時器Timer致命缺點(diǎn)案例詳解

 更新時間:2022年02月17日 09:07:28   作者:叫練  
這篇文章主要介紹了Java中定時器Timer致命缺點(diǎn),以Java中定時器Time為案例整理下我的學(xué)習(xí)方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下

簡介

  這篇文章我一直在糾結(jié)到底要不要寫,不想寫一來因?yàn)槎〞r器用法比較簡單,二來是面試中也不常問。后來還是決定寫了主要是想把自己分析問題思路分享給大家,讓大家在學(xué)習(xí)過程中能夠參考,學(xué)習(xí)態(tài)度我相信大部分人沒有問題,特別是正在看我博文的小伙伴那更不用說了?。〗o你們點(diǎn)個狂力贊。接下來就是學(xué)習(xí)方法了,我發(fā)現(xiàn)近期來咨詢我問題的小伙伴學(xué)習(xí)姿勢不對,所以我用Java中定時器Timer為案例整理下我的學(xué)習(xí)方法。萬丈高樓平地起,所以我一貫的做法都是先用最簡單,最簡單,最簡單案例先行!那就先來個Hello World吧!

案例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啟動后內(nèi)置線程不銷毀
 * @modified By:
 */
public class TimerThreadNoStopTest {
    //TimerTask為抽象類,繼承TimerTask類必須要實(shí)現(xiàn)里面抽象方法
    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線程;程序按傳入日期運(yùn)行
        timer.schedule(task,new Date(currenTime));
}

  如上面程序代碼,Timer提交了一個task任務(wù)并傳入了currenTime當(dāng)前時間,控制臺馬上打印了"hello world!",如果schedule傳入的第二個參數(shù)是new Date(currenTime+2000)表示延遲2m執(zhí)行task任務(wù),這里簡單使用方法就不過多的描述了,但是大家在學(xué)習(xí)過程中遇到疑惑的問題一定要多嘗試多寫代碼測試,這是理解代碼必不可少的一部分,不要以為能看懂就不寫了,像我在學(xué)習(xí)過程中,如果稍微有疑問,我會立馬動手寫代碼測試,因?yàn)槲抑烙袝r候自己可能懂了,但那可能不是真正的懂,只有代碼能檢驗(yàn)出來!下圖是程序控制臺打印結(jié)果。如果大家執(zhí)行了你會發(fā)現(xiàn)一個問題,程序一直不結(jié)束運(yùn)行,也就是程序不死。那是什么導(dǎo)致這樣的結(jié)果呢?

線程不死問題?

  原因分析:如下圖所示,主線程執(zhí)行Timer timer = new Timer();會創(chuàng)建了一個新的子線程timer,timer線程通過死循環(huán)來取隊(duì)列里面的任務(wù)task[1],隊(duì)列其實(shí)就是一個數(shù)組實(shí)現(xiàn)TaskQueue,隊(duì)列里面如果沒有任務(wù),那timer線程就會一直等待直到主線程調(diào)用schedule提交任務(wù),主線程就會將task加入到TaskQueue隊(duì)列數(shù)組并通知timer線程執(zhí)行任務(wù)并刪除隊(duì)列的第一個任務(wù),如果是主線程提交的是定時任務(wù),就會將任務(wù)重新加入隊(duì)列,任務(wù)執(zhí)行完畢后,如果此時隊(duì)列為空,timer線程就會繼續(xù)等待任務(wù)提交到隊(duì)列,一直會循環(huán)上面的過程。如果想退出timer線程,可以調(diào)用cancel方法會退出死循環(huán)。線程不死原因是timer線程一直在等待主線程提交任務(wù),timer線程和主線程通信是通過調(diào)用wait/notify實(shí)現(xiàn)。我們之前做生產(chǎn)者/消費(fèi)者案例時詳細(xì)介紹過,這里老鐵不再重復(fù)敘述了,可以去翻看文章《母雞下蛋實(shí)例》。這個過程中,我們發(fā)現(xiàn)timer是一個單線程,我是單線程怎么了?單線程也有錯嗎?思考個問題,如果timer這個單線程提交了兩個任務(wù)怎么辦?我們看下面代碼!

案例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:多任務(wù)執(zhí)行測試,任務(wù)只能順序執(zhí)行;
 * @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 {
            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("當(dāng)前時間:"+SIMPLE_DATE_FORMAT.format(curTime));
        timer.schedule(myTask1,new Date(curTime));
        //myTask1執(zhí)行時間過長,myTask2 被執(zhí)行時間會被延遲;
        timer.schedule(myTask2,new Date(curTime+1000));
}

  如上面程序代碼,timer線程提交了兩個任務(wù)myTask1,myTask2,myTask1任務(wù)會立刻執(zhí)行,myTask2計劃延遲一秒執(zhí)行,myTask1執(zhí)行過程中會休息10秒鐘,我們觀察任務(wù)執(zhí)行時間如下圖所示,myTask2任務(wù)是等待myTask1任務(wù)執(zhí)行完畢后再執(zhí)行的,其實(shí)myTask2只是延遲一秒執(zhí)行,結(jié)果卻延遲了10秒,說明了timer單線程會串行化任務(wù)導(dǎo)致myTask2延遲執(zhí)行,所以Timer是適合輕量級定時任務(wù),如果設(shè)置大量任務(wù),可能會存在延遲執(zhí)行情況。

定時器實(shí)際應(yīng)用場景

  在日常系統(tǒng)開發(fā)中,相信你遇到過類似需要重復(fù)執(zhí)行的任務(wù),比如每天凌晨2點(diǎn)清理數(shù)據(jù)庫某張表的垃圾數(shù)據(jù),頁面顯示設(shè)備(服務(wù)器)運(yùn)行狀態(tài)也需要每隔3秒調(diào)用設(shè)備狀態(tài)接口查詢設(shè)備情況等,這些功能開發(fā)都需要用到定時器,當(dāng)然Timer定時器也有自身的缺陷,比如它是單線程的,后面會說到線程池中的定時器是多線程的,可以優(yōu)化Timer,所以掌握Timer定時器為后面學(xué)習(xí)高階內(nèi)容打好基礎(chǔ)。知其然知其所以然,在實(shí)際應(yīng)用中我們能得心應(yīng)手!

學(xué)習(xí)方法心得

  大家可以看到我最近幾篇文章分析多線程花了不少精力都在談?wù)摽梢娦?,原子性,母雞下蛋生成消費(fèi)問題等問題,因?yàn)檫@些特性是理解多線程的基礎(chǔ),在我看來基礎(chǔ)又特別重要,所以怎么反復(fù)寫我認(rèn)為都不過分,在這之前有很多新手或者有2到3年工作經(jīng)驗(yàn)的童鞋經(jīng)常會問我關(guān)于Java的學(xué)習(xí)方法,還有一大批童鞋一上來就要做springboot,ssm項(xiàng)目,我是不建議這么干的,你在做項(xiàng)目之前先要了解下servlet,mvc思想啊,這是基礎(chǔ)。我給他們的建議就是要扎實(shí)基礎(chǔ),別上來就學(xué)高級的知識點(diǎn)或者框架,比如ReentrantLock源碼,線程池框架,就像你玩游戲,一開始你就玩難度級別比較高的,一旦坡度比較高你就會比較難受吃力更別說對著書本了,這就是真正的從入門到放棄的過程。同時在學(xué)習(xí)的時候別光思考,覺得這個知識點(diǎn)自己會了就過了,這是不夠的需要多寫代碼,多實(shí)踐,你在這個過程中再去加深自己對知識的理解與記憶,其實(shí)有很多知識你看起來是理解了,但是你沒有動手去實(shí)踐,也沒有真正理解,這樣只看不做的方法我是不推薦的,本人本科畢業(yè)后工作7年,一直從事Java一線的研發(fā)工作,擔(dān)任Java高級研發(fā)工程師,中間也帶過團(tuán)隊(duì),因?yàn)樽约涸?jīng)踏著坑過來的,對學(xué)習(xí)程序還是有一定的心得體會,我會在今后的日子里持續(xù)整理把一些經(jīng)驗(yàn)和知識方面的經(jīng)歷分享給大家,希望大家喜歡關(guān)注我。我是叫練,叫個口號就開始練!

總結(jié)下來就是兩句話:多動手,扎實(shí)基礎(chǔ),從簡單做起,然后慢慢深入!

總結(jié)

  我們用代碼簡述timer定時器提交任務(wù),并說明了timer是單線程的適合輕量級的定時任務(wù),這是它的缺陷。

到此這篇關(guān)于Java中定時器Timer致命缺點(diǎn)(附學(xué)習(xí)方法)的文章就介紹到這了,更多相關(guān)Java定時器Timer內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一篇文章帶你入門java方法

    一篇文章帶你入門java方法

    這篇文章主要介紹了java基礎(chǔ)之方法詳解,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-08-08
  • 關(guān)于Mybatis使用collection分頁問題

    關(guān)于Mybatis使用collection分頁問題

    項(xiàng)目中mybatis分頁的場景是非常高頻的,當(dāng)使用ResultMap并配置collection做分頁的時候,我們可能會遇到獲取當(dāng)前頁的數(shù)據(jù)少于每頁大小的數(shù)據(jù)問題。接下來通過本文給大家介紹Mybatis使用collection分頁問題,感興趣的朋友一起看看吧
    2021-11-11
  • Feign如何解決服務(wù)之間調(diào)用傳遞token

    Feign如何解決服務(wù)之間調(diào)用傳遞token

    這篇文章主要介紹了Feign如何解決服務(wù)之間調(diào)用傳遞token,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 淺析Java集合及LIst接口

    淺析Java集合及LIst接口

    這篇文章主要介紹了Java集合及LIst接口,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 如何替換@PathVariable中的變量

    如何替換@PathVariable中的變量

    這篇文章主要介紹了如何替換@PathVariable中的變量,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java技術(shù)匯總

    Java技術(shù)匯總

    本篇文章主要對Java基本知識點(diǎn)和技術(shù)點(diǎn)的一些看法和介紹,具有很好的參考價值。下面跟著小編一起來看下吧
    2017-03-03
  • java實(shí)現(xiàn)emqx設(shè)備上下線監(jiān)聽詳解

    java實(shí)現(xiàn)emqx設(shè)備上下線監(jiān)聽詳解

    這篇文章主要為大家介紹了java實(shí)現(xiàn)emqx設(shè)備上下線監(jiān)聽詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Java中的Native關(guān)鍵字講解

    Java中的Native關(guān)鍵字講解

    本文介紹了Java中的Native關(guān)鍵字,native關(guān)鍵字是架起本機(jī)語言和JAVA之間鴻溝的橋梁。如果我們的軟件與硬件的交互在使用預(yù)先存在的代碼時更有效,那么這可以作為一個關(guān)鍵環(huán)節(jié)。與從頭開始設(shè)計新的應(yīng)用程序代碼相比,只要可以避免,它就可以使實(shí)現(xiàn)工作更少,下面來了解集體內(nèi)容
    2021-12-12
  • Java處理日期時間的方法匯總

    Java處理日期時間的方法匯總

    這篇文章主要給大家介紹了利用Java中的Calendar 類處理日期時間的方法匯總,其中包括取日期的每部分、取當(dāng)月的第一天或最后一天、求兩個日期之間相隔的天數(shù)以及一年前的日期等等的示例代碼,有需要的朋友們可以直接參考借鑒,下面來一起看看吧。
    2016-12-12
  • SpringBoot實(shí)現(xiàn)登錄攔截的示例代碼

    SpringBoot實(shí)現(xiàn)登錄攔截的示例代碼

    如果我們不進(jìn)行登錄攔截的話,即使我們跳過登錄頁面直接去訪問任意一個頁面也能訪問成功,那么登錄功能就沒有意義,同時也會存在安全問題,本文就來介紹一下SpringBoot登錄攔截,具有一定的參考價值,感興趣的可以了解一下
    2023-09-09

最新評論