標籤: 台北網頁設計公司

  • java面試題-Java集合相關

    java面試題-Java集合相關

    1. ArrayList 和Vector 的區別

      ArrayList和Vector底層實現原理都是一樣得,都是使用數組方式存儲數據

      Vector是線程安全的,但是性能比ArrayList要低。

      ArrayList,Vector主要區別為以下幾點:

       (1):Vector是線程安全的,源碼中有很多的synchronized可以看出,而ArrayList不是。導致Vector效率無法和ArrayList相比;

          (2):ArrayList和Vector都採用線性連續存儲空間,當存儲空間不足的時候,ArrayList默認增加為原來的50%,Vector默認增加為原來的一倍;

       (3):Vector可以設置capacityIncrement,而ArrayList不可以,從字面理解就是capacity容量,Increment增加,容量增長的參數。

     

    2.說說ArrayList,Vector, LinkedList 的存儲性能和特性

      ArrayList採用的數組形式來保存對象,這種方法將對象放在連續的位置中,所以最大的缺點就是插入和刪除的時候比較麻煩,查找比較快;

      Vector使用了sychronized方法(線程安全),所以在性能上比ArrayList要差些.

      LinkedList採用的鏈表將對象存放在獨立的空間中,而且在每個空間中還保存下一個鏈表的索引。使用雙向鏈表方式存儲數據,按序號索引數據需要前向或後向遍曆數據,所以索引數據慢,是插入數據時只需要記錄前後項即可,所以插入的速度快。

     

    3.快速失敗(fail-fast) 和安全失敗(fail-safe) 的區別是什麼?

      1.快速失敗

      原理是:

            迭代器在遍歷時直接訪問集合中的內容,並且在遍歷過程中使用一個modCount變量。集合在被遍歷期間如果內容發生變化,就會改變modCount的值。每當迭代器使用hasNext()或next()遍歷下一個元素之前,都會先檢查modCount變量是否為expectmodCount值。如果是的話就返回遍歷;否則拋出異常,終止遍歷。

      查看ArrayList源碼,在next方法執行的時候,會執行checkForComodification()方法。

           

            @SuppressWarnings("unchecked")
            public E next() {
                checkForComodification();
                int i = cursor;
                if (i >= size)
                    throw new NoSuchElementException();
                Object[] elementData = ArrayList.this.elementData;
                if (i >= elementData.length)
                    throw new ConcurrentModificationException();
                cursor = i + 1 ;
                 return (E) elementData[lastRet = i];
            }
            final  void checkForComodification() {
                 if (modCount != expectedModCount)
                     throw  new ConcurrentModificationException();
            }

      這裏異常的拋出條件是modCount != expectedModCount這個條件。如果集合發生變化時修改modCount值剛好又設置為了expectedModCount值,則異常不會拋出。因此,不能依賴於這個異常是否拋出而進行併發操作,這個異常只建議用於檢測併發修改的bug。

      2.安全失敗

        採用安全失敗機制的集合容器,在遍歷時不是直接在集合上訪問的,而是先複製原有集合內容,在拷貝的集合上進行遍歷。

      原理:

              由於迭代時是對原集合的拷貝進行遍歷,所以在遍歷過程中對原集合所做的修改並不能被迭代器檢測到,所以不會觸發ConcurrentModificationException,例如CopyOnWriteArrayList。

      缺點:

              基於拷貝內容的優點是避免了ConcurrentModificationException,但同樣地,迭代器並不能訪問到修改後的內容。即:迭代器遍歷的是開始遍歷那一刻拿到的集合拷貝,在遍歷期間原集合發生的修改迭代器是不知道的。

      場景:

              Java.util.concurrent包下的容器都是安全失敗的,可以在多線程下併發使用,併發修改。

            快速失敗和安全失敗都是對迭代器而言的。快速失敗:當在迭代一個集合時,如果有另外一個線程在修改這個集合,就會跑出ConcurrentModificationException,java.util下都是快速失敗。安全失敗:在迭代時候會在集合二層做一個拷貝,所以在修改集合上層元素不會影響下層。在java.util.concurrent包下都是安全失敗。

     

    4.HashMap 的數據結構

      HashMap的主幹類是一個Entry數組(jdk1.7) ,每個Entry都包含有一個鍵值隊(key-value).

      我們可以看一下源碼:

    static  class Entry<K,V> implements Map.Entry<K,V> {
             final K key;
            V value;
            Entry <K,V> next; // 存儲指向下一個Entry的引用,單鏈表結構
            int hash; // 對key的hashcode值進行hash運算後得到的值,存儲在Entry,避免重複計算
    
            /**
             * Creates new entry.
             */ 
            Entry( int h, K k, V v, Entry<K,V> n) {
                value = v;
                next = n;
                key = k;
                hash = h;
            }

      所以,HashMap的整體結果如下

      

     

       簡單來說,HashMap由數組+鏈表組成的,數組是HashMap的主體,鏈表則是主要為了解決哈希衝突而存在的,如果定位到的數組位置不含鏈表(當前entry的next指向null ),那麼對於查找,添加等操作很快,僅需一次尋址即可;如果定位到的數組包含鏈表,對於添加操作,其時間複雜度為O(n),首先遍歷鏈表,存在即覆蓋,否則新增;對於查找操作來講,仍需遍歷鏈表,然後通過key對象的equals方法逐一比對查找。所以,性能考慮,HashMap中的鏈表出現越少,性能才會越好。

     

    5.HashMap 的工作原理

      HashMap基於hashing原理,我們通過put()和get()方法存儲和獲取對象,當我們將鍵值對傳遞給put()方法時,它調用鍵對象的hashCode()方法來計算hashcode,讓後找到bucket位置來存儲值對象。當獲取對象時,通過鍵對象的equals()方法找到正確的鍵值對,然後返回對象。

      我們看一下put()源碼:

    public V put(K key, V value) {
             // 當key為null,調用putForNullKey方法,保存null與table第一個位置中,這是HashMap允許為null的原因
            if (key == null )
                 return putForNullKey( value);
             // 計算key的hash值
            int hash = hash(key.hashCode());                   // 計算key hash值在table數組中的位置
            int i = indexFor(hash, table.length);              // 從i出開始迭代e,找到key保存的位置
            for (Entry<K, V> e = table[i]; e != null ; e = e.next) {
                Object k;
                // 判斷該條鏈上是否有hash值相同的(key相同)
                 // 若存在相同,則直接覆蓋value,返回舊value 
                if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                    V oldValue = e.value;     // 舊值=新值 
                    e.value = value;
                    e.recordAccess( this );
                     return oldValue;      // 返回舊值
                }
            }
            // 修改次數增加1 
            modCount++ ;
             // 將key、value添加至i位置處
            addEntry(hash, key, value, i);
             return  null ;
        }

      通過源碼我們可以清晰看到HashMap保存數據的過程為:首先判斷key是否為null,若為null,則直接調用putForNullKey方法。若不為空則先計算key的hash值,然後根據hash值搜索在table數組中的索引位置,如果table數組在該位置處有元素,則通過比較是否存在相同的key,若存在則覆蓋原來key的value,否則將該元素保存在鏈頭(最先保存的元素放在鏈尾)。若table在該處沒有元素,則直接保存。

      get()源碼: 

    public V get(Object key) {
             // 若為null,調用getForNullKey方法返回相對應的value 
            if (key == null )
                 return getForNullKey();
             // 根據該key的hashCode值計算它的hash碼   
            int hash = hash(key.hashCode());
             // 取出table數組中指定索引處的值
            for (Entry<K, V> e = table[indexFor(hash, table.length)]; e != null ; e = e .next) {
                Object k;
                // 若搜索的key與查找的key相同,則返回相對應的value 
                if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
                     return e .value;
            }
            return  null ;
        }

      在這裡能夠根據key快速的取到value除了和HashMap的數據結構密不可分外,還和Entry有莫大的關係,在前面就提到過,HashMap在存儲過程中並沒有將key,value分開來存儲,而是當做一個整體key-value來處理的,這個整體就是Entry對象。同時value也只相當於key的附屬而已。在存儲的過程中,系統根據key的hashcode來決定Entry在table數組中的存儲位置,在取的過程中同樣根據key的hashcode取出相對應的Entry對象。

     

    6.Hashmap 什麼時候進行擴容呢?

      這裏我們再來複習put的流程:當我們想一個HashMap中添加一對key-value時,系統首先會計算key的hash值,然後根據hash值確認在table中存儲的位置。若該位置沒有元素,則直接插入。否則迭代該處元素鏈表並依此比較其key的hash值。如果兩個hash值相等且key值相等(e.hash == hash && ((k = e.key) == key || key.equals(k))),則用新的Entry的value覆蓋原來節點的value。如果兩個hash值相等但key值不等,則將該節點插入該鏈表的鏈頭。具體的實現過程見addEntry方法,如下:

    void addEntry( int hash, K key, V value, int bucketIndex) {
             // 獲取bucketIndex處的Entry 
            Entry<K, V> e = table[bucketIndex];
             // 將新創建的Entry放入bucketIndex索引處,並讓新的Entry指向原來的Entry 
            table[bucketIndex] = new Entry<K, V> (hash, key, value, e);
             // 若HashMap中元素的個數超過極限了,則容量擴大兩倍
            if ( size++ >= threshold)
                resize( 2 * table.length);
        }

      這個方法中有兩點需要注意:

          一是鏈的產生。這是一個非常優雅的設計。系統總是將新的Entry對象添加到bucketIndex處。如果bucketIndex處已經有了對象,那麼新添加的Entry對象將指向原有的Entry對象,形成一條Entry鏈,但是若bucketIndex處沒有Entry對象,也就是e==null,那麼新添加的Entry對象指向null ,也就不會產生Entry鏈了。

          二、擴容問題。

          隨著HashMap中元素的數量越來越多,發生碰撞的概率就越來越大,所產生的鏈表長度就會越來越長,這樣勢必會影響HashMap的速度,為了保證HashMap的效率,系統必須要在某個臨界點進行擴容處理。該臨界點在當HashMap中元素的數量等於table數組長度*加載因子。但是擴容是一個非常耗時的過程,因為它需要重新計算這些數據在新table數組中的位置並進行複製處理。所以如果我們已經預知HashMap中元素的個數,那麼預設元素的個數能夠有效的提高HashMap的性能。

     

     7.HashSet怎樣保證元素不重複

      都知道HashSet中不能存放重複的元素,有時候可以用來做去重操作。但是其內部是怎麼保證元素不重複的呢?

      打開HashSet源碼,發現其內部維護一個HashMap:

    public  class HashSet<E> 
        extends AbstractSet <E> 
        implements Set <E> , Cloneable, java.io.Serializable
    {
        static final long serialVersionUID = - 5024744406713321676L ;
    
        private transient HashMap<E,Object> map;
    
        private  static final Object PRESENT = new Object();
    
     
        public HashSet() {
            map = new HashMap<> ();
        } 
      ...
    }

      HashSet的構造方法其實就是在內部實例化了一個HashMap對象,其中還會看到一個static final的PRESENT變量;

      想知道為什麼HashSet不能存放重複對象,那麼第一步看看它的add方法進行的判重,代碼如下

        public  boolean add(E e) {
             return map.put(e, PRESENT)== null ;
        }

      其實看add()方法,這時候答案已經出來了:HashMap的key是不能重複的,而這裏HashSet的元素又是作為了map的key,當然也不能重複了

      順便看一下HashMap裏面又是怎麼保證key不重複的,代碼如下:

    public V put(K key, V value) {
         if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
        if (key == null )
             return putForNullKey(value);
         int hash = hash(key);
         int i = indexFor(hash, table.length);
         for (Entry<K,V> e = table[i]; e ! = null ; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess( this );
                 return oldValue;
            }
        }
    
        modCount ++ ;
        addEntry(hash, key, value, i);
        return  null ;
    }

      其中最關鍵的一句: 

    if (e.hash == hash && ((k = e.key) == key || key.equals(k)))

      調用了對象的hashCode和equals方法進行判斷,所以又得到一個結論:若要將對象存放到HashSet中並保證對像不重複,應根據實際情況將對象的hashCode方法和equals方法進行重寫

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

    網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

    ※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

    小三通海運與一般國際貿易有何不同?

    小三通快遞通關作業有哪些?

  • 屋頂不夠用沒關係 日開發新太陽能建材 突破瓶頸

    文:宋瑞文(加州能源特約撰述)

    本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

    網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

    ※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

    小三通海運與一般國際貿易有何不同?

    小三通快遞通關作業有哪些?

  • 歐洲太空總署監測 2019巴西亞馬遜大火面積與長期平均相去不遠

    歐洲太空總署監測 2019巴西亞馬遜大火面積與長期平均相去不遠

    環境資訊中心外電;姜唯 翻譯;林大利 審校;稿源:ENS

    去年亞馬遜地區發生了數千起森林大火,引發國際媒體關注。但是,科學家詳細分析歐洲太空總署(European Space Agency, ESA)氣候變遷倡議(Climate Change Initiative)的資料發現,巴西2019年的火災數與2018年相比的確略有增加,與過去18年每年平均火災數比卻相去不遠。

    亞馬遜經常發生森林火災,但每年因氣候變遷、森林砍伐和森林劣化狀況的不同,火災數量也變化很大。

    去年,國際社會密切關注世界各地的森林火災發展,呼籲透過即時火災資訊因應林火,尤其針對巴西。然而,這些數字從未與亞馬遜地區長期以來的火災次數相比較。

    從國際太空站拍攝的亞馬遜森林大火。照片來源:歐洲太空總署

    最近發表在《遙測》期刊上的一篇論文使用歐洲太空總署火災CCI專案的資料,詳細分析南美洲2018年和2019年均森林火災面積,並和2001至2018年平均值比較。

    研究作者來自西班牙阿爾卡拉大學,地質地理與環境系的環境遙測研究小組。他們發現,與2018年同期相比,2019年南美洲燃燒總面積增加了約70%,但僅略高於過去17年的年平均值。

    與長期平均相比,巴西2019年的燃燒面積僅多了1.7%。玻利維亞的數字就很可觀了,與年平均相比,該國2019年的燃燒面積增加了51.4%。

    主持火災CCI專案的科學家、研究作者之一Emilio Chuvieco說:「此類研究對於量化和監控亞馬遜等地的火災活動很重要,但也凸顯長期資料的重要性,並且必須使用更高解析度的感測器,如Copernicus Sentinel-2多光譜儀器,來進行研究,以偵測火災。」

    觀察地球的衛星可用來監測易起火地區的火災。燃燒面積的估計值來自ESA的「火災氣候變遷倡議」專案,屬於ESA氣候變遷倡議的一部分,可從衛星取得燃燒面積的長期資料集。

    這些資料提供穩定的燃燒區域時間序列,對於長期燃燒規律、火災管理和排放分析以及氣候變遷的研究者來說非常有用。

    從國際太空站拍攝的亞馬遜森林大火。照片來源:照片來源:歐洲太空總署

    過去的幾十年間,亞馬遜地區的人為壓力一直在增加,主要與農業擴張有關。研究顯示,該地區火災不斷增加與森林砍伐和森林劣化密切相關。

    ESA地球觀測計畫主任Josef Aschbacher說:「觀測結果顯示,地球和森林中的動態過程不斷在變化,這是我們的挑戰。2019年火災活動的異常增加顯示,衛星資料對於取得清晰、獨立的影像並了解長期趨勢來說非常重要。」

    熱帶森林占世界生物多樣性近一半,是地球生態系統的基本要素。目前進行中的氣候研究都不能缺少森林火災的量化資料,因為火災產生大量碳排放,影響全球溫室氣體預算。」

    科學家得出結論:「大致上來說,南美洲的森林火災政治爭議,焦點應是玻利維亞和委內瑞拉而非巴西,因為巴西2019年的燃燒面積雖比前一年大,長期看來仍在平均水準附近……」

    「但是,亞馬遜地區2019年的火災大多發生在以前很少或不曾發生過火災的地區,包括巴西、玻利維亞、巴拉圭、委內瑞拉和秘魯,是值得深入探討的問題。」科學家指出,「許多研究發現,農業擴張是這些地區發生火災的原因,但還需要進行更詳細的研究才能確認火源。」

    Amazon’s 2019 Burned Area Trends Parallel Past 18 Years ALCALA de HENARES, Spain, March 6, 2020 (ENS)

    Thousands of fires broke out in the Amazon last year, sparking international media alarm. But a detailed analysis, using data from the European Space Agency’s Climate Change Initiative, shows that while there was a small increase of fires in 2019 compared to 2018, the number of fires in Brazil was similar to the average annual number of fires detected over the past 18 years.

    While forest fires are common in the Amazon, they vary considerably from year-to-year driven by changes in climate, as well as variations in deforestation and forest degradation.

    The attention on fires last year, which created great international concern crossing the limits of national policies, prompted an international demand for up-to-date information on active fires, particularly in Brazil.

    Yet these numbers were never compared to the number of fires in the Amazon over a longer period of time.

    Detailed in a recent paper published in the journal “Remote Sensing,” scientists using data from the European Space Agency’s Fire CCI project <ENS

    二氧化碳排放
    大火
    森林野火
    國際新聞
    南美洲
    巴西
    玻利維亞
    委內瑞拉
    全球變遷
    溫室氣體

    作者

    姜唯

    如果有一件事是重要的,如果能為孩子實現一個願望,那就是人類與大自然和諧共存。

    林大利

    於特有生物研究保育中心服務,小鳥和棲地是主要的研究對象。是龜毛的讀者,認為龜毛是探索世界的美德。

    延伸閱讀

    本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

    ※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

    ※Google地圖已可更新顯示潭子電動車充電站設置地點!!

    ※帶您來看台北網站建置台北網頁設計,各種案例分享

    小三通物流營運型態?

    ※快速運回,大陸空運推薦?

  • 比亞迪將在太原打造中西部首個純電動客車、專用車基地

    3月25日,“太原比亞迪新能源汽車基地奠基儀式”在太原經濟技術開發區舉行。比亞迪將在太原打造中西部地區首個以純電動客車、專用車、工礦作業車為重點領域的新能源汽車製造與研發基地。

    根據規劃,太原比亞迪新能源汽車基地位於太原市經濟技術開發區太太路(西攢村),專案分兩期建設,計畫總投資40億元人民幣,占地1100畝,規劃年產5000輛純電動客車、5000輛純電動專用車和2000輛工礦作業車生產能力。兩期工程全部建成投產後,可實現年產值超過150億元。此外,比亞迪還將進駐山西省科創城,成立純電動工礦作業車研發中心,全面深化新能源汽車“7+4”全市場戰略佈局。

    未來,太原比亞迪基地將立足山西,在輻射中西部的同時,面向中、西、南亞,構建山西省新能源汽車產業核心競爭力,積極融入國家“一帶一路”經濟圈。

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

    網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

    ※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

    小三通海運與一般國際貿易有何不同?

    小三通快遞通關作業有哪些?

  • 中國首個!長安無人駕駛將實現2000公里路試

    日前,長安汽車正式公佈,4月12日,其無人駕駛汽車將從重慶出發,途經西安、鄭州,抵達北京,參加北京國際車展,全程超過2000公里,成為中國首個實現長距離無人駕駛的汽車企業。

    長安汽車工程研究院的總工程師黎予生稱,其實這條線已經試跑多次。據悉,這批正在試跑,並在北京車展正式亮相的無人駕駛測試車,將成為2018年長安量產無人駕駛車的原型車。目前長安自動駕駛測試車的最高時速可達150公里/小時,按照國家的標準設定到120公里/小時。

    長安汽車大概6-7年前開始研究自動駕駛技術,3年前正式著手研究無人駕駛系統,制定了“654”智慧化戰略,六大平臺、五大核心技術,分四個階段逐步實現。現在,長安汽車已掌握60余項智慧化技術,特別是結構化道路無人駕駛技術已通過實車性技術驗證。

    重慶到北京的無人駕駛測試就實現了自動駕駛三級水準,能夠實現結構化道路自動駕駛,包括全速自我調整巡航、交通擁堵輔助、車道對中、交通資訊識別、自動換道和非結構化道路接管提醒等。本次重慶到北京的實路演示,是對以上三級自動駕駛的主要功能和技術進行真實道路測試,將為後續工程開發和性能匹配提供實踐經驗。

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

    ※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

    ※Google地圖已可更新顯示潭子電動車充電站設置地點!!

    ※帶您來看台北網站建置台北網頁設計,各種案例分享

    小三通物流營運型態?

    ※快速運回,大陸空運推薦?

  • 【Spring】Spring的定時任務註解@Scheduled原來如此簡單

    【Spring】Spring的定時任務註解@Scheduled原來如此簡單

    1 簡介

    定時任務的實現非常多,JDK的Timer、Spring提供的輕量級的Scheduled TaskQuartZLinux Cron等,還有一些分佈式的任務調度框架。本文主要介紹Scheduled Task的使用。

    2 方便的4種方式

    註解@Scheduled只能用於滿足下面兩個條件的方法上:

    (1)沒有返回類型,或者說返回類型為void

    (2)沒有參數;

    開啟Spring的Scheduler非常簡單,一個註解@EnableScheduling即可:

    @Configuration
    @EnableScheduling
    public class SchedulingConfig {
    }

    如果是Springboot應用,則直接在啟動類上面加上@EnableScheduling就可以使用了。

    2.1 固定延遲fixedDelay

    代表下一個任務的開始與上一個任務的結束間隔總是固定的時長,而且總是會等上一個任務完成了,才會開啟下一個任務。如果需求是有這樣依賴要求的,使用這種模式是非常合適的。代碼如下:

    @Scheduled(fixedDelay = 1000)
    public void fixedDelay() {
      log.info("fixedDelay");
    }

    參數為1000,代表固定延遲為1000毫秒,即1秒鐘,所以輸出為:

    2019-11-19 21:02:43,977 scheduling-1:fixedDelay 
    2019-11-19 21:02:44,981 scheduling-1:fixedDelay 
    2019-11-19 21:02:45,983 scheduling-1:fixedDelay 
    2019-11-19 21:02:46,984 scheduling-1:fixedDelay 

    2.2 固定頻率fixedRate

    2.2.1 正常情況

    定頻任務的特性是任務的執行的時間間隔總是一樣的。比如每1小時執行一次,就是任務執行開始的時間點的時間間隔為1小時。代碼如下:

    @Scheduled(fixedRate = 2000)
    public void fixedRate() {
      log.info("fixedRate");
    }

    參數為2000,則每2秒執行一次,輸出為:

    2019-11-19 21:38:45,073 scheduling-1:fixedRate 
    2019-11-19 21:38:47,076 scheduling-1:fixedRate 
    2019-11-19 21:38:49,073 scheduling-1:fixedRate 
    2019-11-19 21:38:51,075 scheduling-1:fixedRate 

    2.2.2 默認單線程

    需要注意的是它默認是單線程的,不會并行執行。即使是固定頻率,但下一次的任務也必須等到上一次任務執行完畢才會開始。下面這個例子能很好說明:

    @Scheduled(fixedRate = 1000)
    public void fixedRateLongTimeTask() throws InterruptedException {
      log.info("fixedRateLongTimeTask");
      Thread.sleep(3000);
    }

    由於任務需要執行3秒才能完成,即使fixedRate設置為1秒,並不能每一秒執行一次,輸出如下:

    2019-11-19 21:46:00,108 scheduling-1:fixedRateLongTimeTask 
    2019-11-19 21:46:03,113 scheduling-1:fixedRateLongTimeTask 
    2019-11-19 21:46:06,113 scheduling-1:fixedRateLongTimeTask 
    2019-11-19 21:46:09,117 scheduling-1:fixedRateLongTimeTask 

    每3次輸出一次。

    2.2.3 註解@Async來幫你

    上述問題有辦法解決嗎?答案是肯定的,而且非常簡單。只需要加一個註解@Async就可以使任務能異步多線程地執行了,代碼如下:

    @Async
    @Scheduled(fixedRate = 1000)
    public void fixedRateLongTimeTask() throws InterruptedException {
      log.info("fixedRateLongTimeTask");
      Thread.sleep(3000);
    }

    通過日誌可以看出是每秒執行一次的,即使前面的任務還沒有完成。而且線程名不一樣,通過多線程來執行,輸出結果為:

    2019-11-19 21:54:22,261 task-5:fixedRateLongTimeTask 
    2019-11-19 21:54:23,257 task-6:fixedRateLongTimeTask 
    2019-11-19 21:54:24,257 task-4:fixedRateLongTimeTask 
    2019-11-19 21:54:25,257 task-8:fixedRateLongTimeTask 
    2019-11-19 21:54:26,259 task-1:fixedRateLongTimeTask 
    2019-11-19 21:54:27,262 task-2:fixedRateLongTimeTask 
    2019-11-19 21:54:28,260 task-3:fixedRateLongTimeTask 

    注意:需要指出的是,需要像@EnableScheduling一樣,需要添加配置註解@EnableAsync來打開這個功能開關。另外,如果任務執行時間很長,例如1分鐘,情況又不一樣。以後再詳細介紹@Async的使用吧。

    2.3 初始延遲initialDelay

    初始延遲是用initialDelay來指定的,它可以延遲第一次任務執行的時間。如下例子的參數為30秒,則在啟動30秒后,才開始執行第一次。可以減輕項目啟動的負擔,也可以為任務執行前準備數據。

    @Scheduled(fixedDelay = 1000, initialDelay = 30*1000)
    public void fixedDelayWithIntialDelay() {
      log.info("fixedDelayWithIntialDelay");
    }

    輸出如下:

    2019-11-19 22:10:02,092 main:Tomcat started on port(s): 443 (http) with context path '' 
    2019-11-19 22:10:02,095 main:Started DemoApplication in 1.272 seconds (JVM running for 1.767) 
    2019-11-19 22:10:32,063 scheduling-1:fixedDelayWithIntialDelay 
    2019-11-19 22:10:33,067 scheduling-1:fixedDelayWithIntialDelay 
    2019-11-19 22:10:34,069 scheduling-1:fixedDelayWithIntialDelay 
    2019-11-19 22:10:35,069 scheduling-1:fixedDelayWithIntialDelay

    可以看出,在項目啟動后30秒左右,才開始執行任務。

    2.4 Cron表達式

    上述提供的功能並不能滿足定時任務調度的所有需求,比如需要每個月1號發送短信,每周六做數據分析等。這裏Cron表達式就派上用場了。

    下面的例子表示每當秒數為06的時候就執行。代碼如下:

    @Scheduled(cron = "6 * * ? * *")
    public void cron() {
      log.info("cron");
    }

    結果如下:

    2019-11-19 22:20:06,003 scheduling-1:cron 
    2019-11-19 22:21:06,004 scheduling-1:cron 
    2019-11-19 22:22:06,002 scheduling-1:cron 

    Cron表達式功能非常強大,網上資料很豐富,這裏不展開講了。

    3 參數配置化

    之前的例子都將參數寫死在代碼上了,如果需要更靈活,其實可以用參數來配置。這樣需要修改參數的時候,不用修改代碼、編譯打包再部署了,直接修改配置文件即可。

    代碼如下:

    @Scheduled(cron = "${pkslow.cron}")
    public void cronWithConfig() {
      log.info("cronWithConfig");
    }

    在application.properties配置如下:

    pkslow.cron=* * * ? * *

    代碼1秒執行一次。

    4 如果她突然消失了

    由於Spring的Scheduler默認是單線程的,這樣會存在一個問題,如果某個任務執行卡住了,那就無法繼續往下執行了。在日誌上表現就是突然消失了。這種情況出現的概率還是不小的,如操作數據庫死鎖了,http請求timeout為無限等待,還有其它原因的死鎖等。

    當遇到這種情況,應通過命令jstack pid > pid.ThreadDump.txt獲取當前線程情況,然後分析是否真的是卡住了,卡在了哪個環節,然後再分析具體代碼。通過設置超時或重試等方法來解決。

    5 結論

    本文主要介紹了Spring的定時任務註解@Scheduled的使用,講述了多種方式的使用和配置。它非常方便簡潔,對於簡單的定時任務足以應對了。

    歡迎關注公眾號<南瓜慢說>,將持續為你更新…

    多讀書,多分享;多寫作,多整理。

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
    【其他文章推薦】

    台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

    網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

    ※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

    小三通海運與一般國際貿易有何不同?

    小三通快遞通關作業有哪些?

  • 社交距離引爆孤獨感 美國認養寵物暴增

    摘錄自2020年03月22日中央通訊社美國報導

    為避免武漢肺炎疫情擴散,包括美國在內,全球許多國家呼籲民眾不要外出留在家。但待在家裡無法與人接觸引發的孤獨感,以及可以空出時間照料,都讓寵物認養數目大幅攀升。

    華盛頓郵報(Washington Post)報導,過去一段時間寵物認養倍增,馬里蘭州蓋瑟斯堡(Gaithersburg)動物救援所過去週日平均約15隻貓狗能找到認養家庭,最近排隊認養的人數從10人增加到40人,3小時就有30隻動物被認養。

    美國愛護動物協會(American Society for the Prevention of Cruelty to Animals)總裁兼執行長薄夏德克爾(Matt Bershadker)透過郵件表示,動物能夠提供舒適感與陪伴感,特別是在危機時刻,他們鼓勵民眾繼續認養或暫時認養動物。

    動物福利
    流浪動物
    國際新聞
    美國
    寵物
    COVID-19

    本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

    網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

    ※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

    小三通海運與一般國際貿易有何不同?

    小三通快遞通關作業有哪些?

  • 日本東京天氣像入夏 櫻花盛開史上第2早

    摘錄自2020年3月22日中央社報導

    日本氣象廳22日宣布,東京的染井吉野櫻已滿開,是全日本最早滿開的地區。氣象廳職員22日已確認位於東京都千代田區靖國神社內的標準木,有8成櫻花開花,比往年早了12天,也比去年早了5天。

    日本讀賣新聞報導,2020年東京都櫻花開花是從1953年開始觀測以來最早的一年,滿開則是次於2002年的3月21日第2早的一年。

    東京都青梅市最高溫來到攝氏27.1度,相當於往年7月上旬的氣溫;東京都八王子市也有26.2度、埼玉縣秩父市有26.7度、茨城縣古河市為25.6度、櫪木縣佐野市有25.4度、群馬縣高崎市也有25.2度。而在沖繩縣宇流麻市及愛媛縣新居濱市,則雙雙創下觀測史上3月最高溫紀錄。

    全球變遷
    全球暖化
    國際新聞
    日本
    東京
    沖繩
    氣候暖化
    高溫紀錄

    本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

    ※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

    ※Google地圖已可更新顯示潭子電動車充電站設置地點!!

    ※帶您來看台北網站建置台北網頁設計,各種案例分享

    小三通物流營運型態?

    ※快速運回,大陸空運推薦?

  • 神州專車與阿裡巴巴將在“互聯網+汽車”領域進行全方位戰略合作

    4月11日,神州專車的運營主體神州優車股份有限公司正式宣佈,已與阿裡巴巴(中國)網路技術有限公司簽署戰略合作協定,結成戰略合作夥伴關係。

    根據協定,雙方將在“互聯網+汽車”領域進行全方位的戰略合作,致力於重塑相關產業鏈及生態體系。 在雙方戰略合作的總體框架下,雙方將首先在汽車電商、大資料行銷、雲計算應用、高精地圖及出行大資料、智慧汽車等各方面推進合作。

    對此,阿裡方面表示,阿裡巴巴與神州優車確已達成戰略合作協定,但阿裡巴巴目前在神州優車沒有股權。

    值得注意的是,神州專車、神州租車與阿裡旅行在業務層面合作早已展開,並已經在阿裡旅行平臺上開設官方旗艦店。神州專車曾對媒體表示,未來神州專車、神州租車還將把用車服務與阿裡旅行出行項目進行諸如“酒店+車”“高爾夫+車”“旅遊路線+車”等形式增值打包。

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包”嚨底家”

    網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

    ※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

    小三通海運與一般國際貿易有何不同?

    小三通快遞通關作業有哪些?

  • 平安保險16億美元收購汽車之家47.7%股權

    日前,中國平安保險(集團)股份有限公司將以16億美元的代價,收購澳大利亞電信手中持有的中國汽車網站汽車之家47.7%的股份。

    有媒體報導稱,平安集團收購澳大利亞電信持有的汽車之家股份只是一個開始。根據計畫,股權收購完成後,以平安集團為首的SPV(特殊目的實體)將對汽車之家發起全面私有化收購要約,預計6-9個月內完成。在後續的私有化過程,騰訊、京東、易車等戰略投資均會參與。私有化後的汽車之家將回歸A股上市。

    平安集團接手之後

    首先:加快汽車之家的私有化進程。有消息傳言稱,或許因為納斯達克上市後行情影響,估值萎縮,平安集團接手之後所建立的新財團,將對汽車之家發起全面私有化收購要約,具體計畫是,新財團將設立一個有限合夥企業投資基金到並購SPV中參與後續的私有化過程,並購將由平安基金主要發起,騰訊、京東、易車等戰略投資均會參與。私有化後的公司將在國內借殼上市,預計會在私有化之後6個月內完成。

    其次:全面覆蓋保險、金融業務。汽車之家的營收主要來自經銷商黃頁業務、汽車廠商廣告服務。但是據CEO秦致透露,汽車之家現在做的經銷商黃頁業務只服務到中國新車經銷商的新車銷售環節,沒有真正覆蓋二手車、售後保養,甚至保險金融服務,相信平安集團接收之後會利用自身能力幫助汽車之家覆蓋這些環節,雙方利益達到最大化。

    第三:共同發力汽車電商領域。年前已有消息稱汽車之家會收購平安集團旗下的平安好車業務,但最終兩者並未達成合作,或許意味著平安集團早有收購汽車之家的意圖。車雲菌曾預測,平安好車關閉並非意味著平安集團真的放棄了二手車這個領域,而是別有意圖。現在情況愈發明朗,例如,汽車之家旗下的二手車業務主要以C2C模式的家家好車為主,兩者或將從家家好車開始,共同發力二手車電商領域。

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

    ※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

    ※Google地圖已可更新顯示潭子電動車充電站設置地點!!

    ※帶您來看台北網站建置台北網頁設計,各種案例分享

    小三通物流營運型態?

    ※快速運回,大陸空運推薦?